mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
waydroidintegrationplugin: Make async and add error checking
Fixes: https://invent.kde.org/plasma/plasma-mobile/-/issues/494
This commit is contained in:
parent
aa070c5985
commit
c7e961ca85
4 changed files with 320 additions and 166 deletions
|
|
@ -73,6 +73,12 @@ void WaydroidApplicationDBusClient::updateName()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidApplicationDBusClient: Failed to fetch name:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto name = reply.argumentAt<0>();
|
||||
|
||||
if (m_name != name) {
|
||||
|
|
@ -90,11 +96,17 @@ void WaydroidApplicationDBusClient::updatePackageName()
|
|||
return;
|
||||
}
|
||||
|
||||
auto reply = m_interface->name();
|
||||
auto reply = m_interface->packageName();
|
||||
auto watcher = new QDBusPendingCallWatcher(reply, this);
|
||||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidApplicationDBusClient: Failed to fetch packageName:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto packageName = reply.argumentAt<0>();
|
||||
|
||||
if (m_packageName != packageName) {
|
||||
|
|
|
|||
|
|
@ -83,6 +83,12 @@ void WaydroidDBusClient::initializeApplicationListModel()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<QList<QDBusObjectPath>> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch applications:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto applications = reply.argumentAt<0>();
|
||||
|
||||
m_applicationListModel->initializeApplications(applications);
|
||||
|
|
@ -90,6 +96,8 @@ void WaydroidDBusClient::initializeApplicationListModel()
|
|||
// Connect applicationListModel signals only when applications is synced
|
||||
connect(m_interface, &OrgKdePlasmashellWaydroidInterface::applicationAdded, m_applicationListModel, &WaydroidApplicationListModel::addApplication);
|
||||
connect(m_interface, &OrgKdePlasmashellWaydroidInterface::applicationRemoved, m_applicationListModel, &WaydroidApplicationListModel::removeApplication);
|
||||
|
||||
watcher->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -161,9 +169,9 @@ QCoro::Task<void> WaydroidDBusClient::setUeventTask(const bool uevent)
|
|||
co_await pendingReply;
|
||||
}
|
||||
|
||||
QCoro::QmlTask WaydroidDBusClient::setUevent(const bool multiWindows)
|
||||
QCoro::QmlTask WaydroidDBusClient::setUevent(const bool uevent)
|
||||
{
|
||||
return setUeventTask(multiWindows);
|
||||
return setUeventTask(uevent);
|
||||
}
|
||||
|
||||
QCoro::Task<void> WaydroidDBusClient::refreshSessionInfoTask()
|
||||
|
|
@ -277,6 +285,12 @@ void WaydroidDBusClient::updateStatus()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch status:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto status = static_cast<Status>(reply.argumentAt<0>());
|
||||
|
||||
if (m_status != status) {
|
||||
|
|
@ -295,6 +309,12 @@ void WaydroidDBusClient::updateSessionStatus()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch sessionStatus:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sessionStatus = static_cast<SessionStatus>(reply.argumentAt<0>());
|
||||
|
||||
if (m_sessionStatus != sessionStatus) {
|
||||
|
|
@ -313,6 +333,12 @@ void WaydroidDBusClient::updateSystemType()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch systemType:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto systemType = static_cast<SystemType>(reply.argumentAt<0>());
|
||||
|
||||
if (m_systemType != systemType) {
|
||||
|
|
@ -331,6 +357,12 @@ void WaydroidDBusClient::updateIpAddress()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch ipAddress:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto ipAddress = reply.argumentAt<0>();
|
||||
|
||||
if (m_ipAddress != ipAddress) {
|
||||
|
|
@ -349,6 +381,12 @@ void WaydroidDBusClient::updateAndroidId()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch androidId:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto androidId = reply.argumentAt<0>();
|
||||
|
||||
if (m_androidId != androidId) {
|
||||
|
|
@ -367,6 +405,12 @@ void WaydroidDBusClient::updateMultiWindows()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<bool> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch multiWindows:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto multiWindows = reply.argumentAt<0>();
|
||||
|
||||
if (m_multiWindows != multiWindows) {
|
||||
|
|
@ -385,6 +429,12 @@ void WaydroidDBusClient::updateSuspend()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<bool> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch suspend:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto suspend = reply.argumentAt<0>();
|
||||
|
||||
if (m_suspend != suspend) {
|
||||
|
|
@ -403,6 +453,12 @@ void WaydroidDBusClient::updateUevent()
|
|||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](auto watcher) {
|
||||
QDBusPendingReply<bool> reply = *watcher;
|
||||
if (!reply.isValid()) {
|
||||
qDebug() << "WaydroidDBusClient: Failed to fetch uevent:" << reply.error().message();
|
||||
watcher->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto uevent = reply.argumentAt<0>();
|
||||
|
||||
if (m_uevent != uevent) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@
|
|||
#include "waydroidintegrationplugin_debug.h"
|
||||
#include "waydroidshared.h"
|
||||
|
||||
#include <QCoroProcess>
|
||||
#include <QDBusConnection>
|
||||
#include <QDir>
|
||||
#include <QLoggingCategory>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
|
|
@ -31,7 +33,7 @@ using namespace Qt::StringLiterals;
|
|||
#define UEVENT_PROP_KEY "persist.waydroid.uevent"
|
||||
|
||||
static const QRegularExpression sessionRegExp(u"Session:\\s*(\\w+)"_s);
|
||||
static const QRegularExpression ipAdressRegExp(u"IP address:\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)"_s);
|
||||
static const QRegularExpression ipAddressRegExp(u"IP address:\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)"_s);
|
||||
static const QRegularExpression systemOtaRegExp(u"system_ota\\s*=\\s*(\\S+)"_s);
|
||||
|
||||
WaydroidDBusObject::WaydroidDBusObject(QObject *parent)
|
||||
|
|
@ -41,7 +43,10 @@ WaydroidDBusObject::WaydroidDBusObject(QObject *parent)
|
|||
|
||||
void WaydroidDBusObject::registerObject()
|
||||
{
|
||||
if (!m_dbusInitialized) {
|
||||
if (m_dbusInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
new WaydroidAdaptor{this};
|
||||
QDBusConnection::sessionBus().registerObject(u"/Waydroid"_s, this);
|
||||
m_dbusInitialized = true;
|
||||
|
|
@ -53,7 +58,6 @@ void WaydroidDBusObject::registerObject()
|
|||
connect(this, &WaydroidDBusObject::sessionStatusChanged, this, &WaydroidDBusObject::refreshApplications);
|
||||
|
||||
refreshSupportsInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::initialize(const int systemType, const int romType, const bool forced)
|
||||
|
|
@ -99,7 +103,6 @@ void WaydroidDBusObject::initialize(const int systemType, const int romType, con
|
|||
writeAction.setTimeout(3600000); // HACK: 1 hour to wait installation
|
||||
|
||||
KAuth::ExecuteJob *job = writeAction.execute();
|
||||
job->start();
|
||||
|
||||
connect(job, &KAuth::ExecuteJob::newData, this, [this](const QVariantMap &data) {
|
||||
QString log = data.value("log", "").toString();
|
||||
|
|
@ -123,6 +126,8 @@ void WaydroidDBusObject::initialize(const int systemType, const int romType, con
|
|||
|
||||
Q_EMIT statusChanged();
|
||||
});
|
||||
|
||||
job->start();
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::startSession()
|
||||
|
|
@ -137,10 +142,10 @@ void WaydroidDBusObject::startSession()
|
|||
const QStringList arguments{u"session"_s, u"start"_s};
|
||||
|
||||
auto *process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
|
||||
connect(process, &QProcess::finished, this, [this, process](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
Q_UNUSED(exitStatus);
|
||||
process->deleteLater();
|
||||
|
||||
if (exitCode == 0) {
|
||||
return;
|
||||
|
|
@ -157,6 +162,8 @@ void WaydroidDBusObject::startSession()
|
|||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to start the Waydroid session: " << errorString;
|
||||
});
|
||||
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
|
||||
checkSessionStarting(10);
|
||||
}
|
||||
|
||||
|
|
@ -168,16 +175,22 @@ void WaydroidDBusObject::stopSession()
|
|||
|
||||
const QStringList arguments{u"session"_s, u"stop"_s};
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
process->waitForFinished();
|
||||
auto *process = new QProcess(this);
|
||||
|
||||
connect(process, &QProcess::finished, this, [this, process](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
Q_UNUSED(exitStatus);
|
||||
process->deleteLater();
|
||||
|
||||
if (exitCode == 0) {
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to stop the Waydroid session: " << process->readAllStandardError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (process->exitCode() == 0) {
|
||||
m_sessionStatus = SessionStopped;
|
||||
Q_EMIT sessionStatusChanged();
|
||||
} else {
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to stop the Waydroid session: " << process->readAllStandardError();
|
||||
}
|
||||
});
|
||||
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::resetWaydroid()
|
||||
|
|
@ -200,7 +213,6 @@ void WaydroidDBusObject::resetWaydroid()
|
|||
writeAction.setArguments(args);
|
||||
|
||||
KAuth::ExecuteJob *job = writeAction.execute();
|
||||
job->start();
|
||||
|
||||
connect(job, &KAuth::ExecuteJob::finished, this, [this](KJob *job, auto) {
|
||||
removeWaydroidApplications();
|
||||
|
|
@ -216,6 +228,8 @@ void WaydroidDBusObject::resetWaydroid()
|
|||
|
||||
Q_EMIT statusChanged();
|
||||
});
|
||||
|
||||
job->start();
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::installApk(const QString apkFile)
|
||||
|
|
@ -223,7 +237,6 @@ void WaydroidDBusObject::installApk(const QString apkFile)
|
|||
const QStringList arguments{u"app"_s, u"install"_s, apkFile};
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
|
||||
connect(process, &QProcess::finished, this, [this, apkFile, process](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
|
||||
|
|
@ -233,6 +246,8 @@ void WaydroidDBusObject::installApk(const QString apkFile)
|
|||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Error occurred during installation of " << apkFile << ": " << process->readAllStandardError();
|
||||
}
|
||||
});
|
||||
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::deleteApplication(const QString appId)
|
||||
|
|
@ -240,7 +255,6 @@ void WaydroidDBusObject::deleteApplication(const QString appId)
|
|||
const QStringList arguments{u"app"_s, u"remove"_s, appId};
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
|
||||
connect(process, &QProcess::finished, this, [this, appId, process](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
Q_UNUSED(exitCode);
|
||||
|
|
@ -256,6 +270,8 @@ void WaydroidDBusObject::deleteApplication(const QString appId)
|
|||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Error occurred during uninstallation of " << appId << ": " << errorLog;
|
||||
}
|
||||
});
|
||||
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
}
|
||||
|
||||
int WaydroidDBusObject::status() const
|
||||
|
|
@ -296,10 +312,17 @@ void WaydroidDBusObject::setMultiWindows(const bool multiWindows)
|
|||
|
||||
const QString value = multiWindows ? "true" : "false";
|
||||
|
||||
if (writePropValue(MULTI_WINDOWS_PROP_KEY, value)) {
|
||||
m_multiWindows = multiWindows;
|
||||
Q_EMIT multiWindowsChanged();
|
||||
// Run coroutine asynchronously with QPointer to safely handle 'this'
|
||||
auto coro = [](WaydroidDBusObject *self, QString value, bool multiWindows) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
if (co_await self->writePropValue(MULTI_WINDOWS_PROP_KEY, value)) {
|
||||
if (guard) {
|
||||
self->m_multiWindows = multiWindows;
|
||||
Q_EMIT self->multiWindowsChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
coro(this, value, multiWindows);
|
||||
}
|
||||
|
||||
bool WaydroidDBusObject::suspend() const
|
||||
|
|
@ -315,10 +338,16 @@ void WaydroidDBusObject::setSuspend(const bool suspend)
|
|||
|
||||
const QString value = suspend ? "true" : "false";
|
||||
|
||||
if (writePropValue(SUSPEND_PROP_KEY, value)) {
|
||||
m_suspend = suspend;
|
||||
Q_EMIT suspendChanged();
|
||||
auto coro = [](WaydroidDBusObject *self, QString value, bool suspend) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
if (co_await self->writePropValue(SUSPEND_PROP_KEY, value)) {
|
||||
if (guard) {
|
||||
self->m_suspend = suspend;
|
||||
Q_EMIT self->suspendChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
coro(this, value, suspend);
|
||||
}
|
||||
|
||||
bool WaydroidDBusObject::uevent() const
|
||||
|
|
@ -334,10 +363,16 @@ void WaydroidDBusObject::setUevent(const bool uevent)
|
|||
|
||||
const QString value = uevent ? "true" : "false";
|
||||
|
||||
if (writePropValue(UEVENT_PROP_KEY, value)) {
|
||||
m_uevent = uevent;
|
||||
Q_EMIT ueventChanged();
|
||||
auto coro = [](WaydroidDBusObject *self, QString value, bool uevent) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
if (co_await self->writePropValue(UEVENT_PROP_KEY, value)) {
|
||||
if (guard) {
|
||||
self->m_uevent = uevent;
|
||||
Q_EMIT self->ueventChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
coro(this, value, uevent);
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> WaydroidDBusObject::applications() const
|
||||
|
|
@ -353,24 +388,30 @@ void WaydroidDBusObject::refreshSupportsInfo()
|
|||
{
|
||||
const QStringList arguments{u"-h"_s};
|
||||
|
||||
auto process = QProcess(this);
|
||||
process.start(WAYDROID_COMMAND, arguments);
|
||||
process.waitForFinished();
|
||||
auto process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
|
||||
const int exitCode = process.exitCode();
|
||||
if (exitCode != 0) {
|
||||
connect(process, &QProcess::finished, this, [this, process](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
Q_UNUSED(exitCode)
|
||||
Q_UNUSED(exitStatus)
|
||||
|
||||
process->deleteLater();
|
||||
|
||||
if (process->exitCode() != 0) {
|
||||
m_status = NotSupported;
|
||||
Q_EMIT statusChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString output = fetchSessionInfo();
|
||||
fetchSessionInfo().then([this](const QString &output) {
|
||||
if (!output.contains("WayDroid is not initialized")) {
|
||||
m_status = Initialized;
|
||||
} else {
|
||||
m_status = NotInitialized;
|
||||
}
|
||||
Q_EMIT statusChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::refreshInstallationInfo()
|
||||
|
|
@ -406,9 +447,15 @@ void WaydroidDBusObject::refreshSessionInfo()
|
|||
return;
|
||||
}
|
||||
|
||||
const QString output = fetchSessionInfo();
|
||||
auto coro = [](WaydroidDBusObject *self) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
const QString output = co_await self->fetchSessionInfo();
|
||||
|
||||
const QString sessionMatchResult = extractRegExp(output, sessionRegExp);
|
||||
if (!guard) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
const QString sessionMatchResult = self->extractRegExp(output, sessionRegExp);
|
||||
SessionStatus newSessionStatus;
|
||||
|
||||
if (!sessionMatchResult.isEmpty()) {
|
||||
|
|
@ -417,24 +464,32 @@ void WaydroidDBusObject::refreshSessionInfo()
|
|||
newSessionStatus = SessionStopped;
|
||||
}
|
||||
|
||||
if (m_sessionStatus != newSessionStatus) {
|
||||
m_sessionStatus = newSessionStatus;
|
||||
Q_EMIT sessionStatusChanged();
|
||||
if (self->m_sessionStatus != newSessionStatus) {
|
||||
self->m_sessionStatus = newSessionStatus;
|
||||
Q_EMIT self->sessionStatusChanged();
|
||||
}
|
||||
|
||||
m_ipAddress = extractRegExp(output, ipAdressRegExp);
|
||||
Q_EMIT ipAddressChanged();
|
||||
const QString newIpAddress = self->extractRegExp(output, ipAddressRegExp);
|
||||
if (self->m_ipAddress != newIpAddress) {
|
||||
self->m_ipAddress = self->extractRegExp(output, ipAddressRegExp);
|
||||
Q_EMIT self->ipAddressChanged();
|
||||
}
|
||||
};
|
||||
coro(this);
|
||||
}
|
||||
|
||||
QString WaydroidDBusObject::fetchSessionInfo()
|
||||
QCoro::Task<QString> WaydroidDBusObject::fetchSessionInfo()
|
||||
{
|
||||
const QStringList arguments{u"status"_s};
|
||||
|
||||
auto process = QProcess(this);
|
||||
process.start(WAYDROID_COMMAND, arguments);
|
||||
process.waitForFinished();
|
||||
auto *basicProcess = new QProcess(this);
|
||||
auto process = qCoro(basicProcess);
|
||||
co_await process.start(WAYDROID_COMMAND, arguments);
|
||||
co_await process.waitForFinished();
|
||||
|
||||
return process.readAllStandardOutput();
|
||||
const QString output = basicProcess->readAllStandardOutput();
|
||||
basicProcess->deleteLater();
|
||||
co_return output;
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::refreshAndroidId()
|
||||
|
|
@ -447,7 +502,6 @@ void WaydroidDBusObject::refreshAndroidId()
|
|||
writeAction.setHelperId(u"org.kde.plasma.mobileshell.waydroidhelper"_s);
|
||||
|
||||
KAuth::ExecuteJob *job = writeAction.execute();
|
||||
job->start();
|
||||
|
||||
connect(job, &KAuth::ExecuteJob::finished, this, [this](KJob *job, auto) {
|
||||
KAuth::ExecuteJob *executeJob = dynamic_cast<KAuth::ExecuteJob *>(job);
|
||||
|
|
@ -464,54 +518,61 @@ void WaydroidDBusObject::refreshAndroidId()
|
|||
|
||||
Q_EMIT androidIdChanged();
|
||||
});
|
||||
|
||||
job->start();
|
||||
}
|
||||
|
||||
void WaydroidDBusObject::refreshPropsInfo()
|
||||
QCoro::Task<void> WaydroidDBusObject::refreshPropsInfo()
|
||||
{
|
||||
if (m_sessionStatus != SessionRunning) {
|
||||
return;
|
||||
co_return;
|
||||
}
|
||||
|
||||
const QString multiWindowsPropValue = fetchPropValue(MULTI_WINDOWS_PROP_KEY, "false");
|
||||
const QString multiWindowsPropValue = co_await fetchPropValue(MULTI_WINDOWS_PROP_KEY, "false");
|
||||
m_multiWindows = multiWindowsPropValue == "true";
|
||||
Q_EMIT multiWindowsChanged();
|
||||
|
||||
const QString suspendPropValue = fetchPropValue(SUSPEND_PROP_KEY, "true");
|
||||
const QString suspendPropValue = co_await fetchPropValue(SUSPEND_PROP_KEY, "true");
|
||||
m_suspend = suspendPropValue == "true";
|
||||
Q_EMIT suspendChanged();
|
||||
|
||||
const QString ueventPropValue = fetchPropValue(UEVENT_PROP_KEY, "false");
|
||||
const QString ueventPropValue = co_await fetchPropValue(UEVENT_PROP_KEY, "false");
|
||||
m_uevent = ueventPropValue == "true";
|
||||
Q_EMIT ueventChanged();
|
||||
}
|
||||
|
||||
QString WaydroidDBusObject::fetchPropValue(const QString key, const QString defaultValue)
|
||||
QCoro::Task<QString> WaydroidDBusObject::fetchPropValue(const QString key, const QString defaultValue)
|
||||
{
|
||||
const QStringList arguments{u"prop"_s, u"get"_s, key};
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
process->start(WAYDROID_COMMAND, arguments);
|
||||
process->waitForFinished();
|
||||
auto *basicProcess = new QProcess(this);
|
||||
auto process = qCoro(basicProcess);
|
||||
co_await process.start(WAYDROID_COMMAND, arguments);
|
||||
co_await process.waitForFinished();
|
||||
|
||||
const QString commandOutput = process->readAllStandardOutput();
|
||||
const QString commandOutput = basicProcess->readAllStandardOutput();
|
||||
basicProcess->deleteLater();
|
||||
const QString value = commandOutput.split("\n").first().trimmed();
|
||||
|
||||
if (value.isEmpty()) {
|
||||
return defaultValue;
|
||||
co_return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
co_return value;
|
||||
}
|
||||
|
||||
bool WaydroidDBusObject::writePropValue(const QString key, const QString value)
|
||||
QCoro::Task<bool> WaydroidDBusObject::writePropValue(const QString key, const QString value)
|
||||
{
|
||||
const QStringList arguments{u"prop"_s, u"set"_s, key, value};
|
||||
|
||||
auto process = QProcess(this);
|
||||
process.start(WAYDROID_COMMAND, arguments);
|
||||
process.waitForFinished();
|
||||
auto *basicProcess = new QProcess(this);
|
||||
auto process = qCoro(basicProcess);
|
||||
co_await process.start(WAYDROID_COMMAND, arguments);
|
||||
co_await process.waitForFinished();
|
||||
|
||||
return process.exitCode() == 0;
|
||||
const bool success = basicProcess->exitCode() == 0;
|
||||
basicProcess->deleteLater();
|
||||
co_return success;
|
||||
}
|
||||
|
||||
QString WaydroidDBusObject::extractRegExp(const QString text, const QRegularExpression regExp) const
|
||||
|
|
@ -531,21 +592,32 @@ void WaydroidDBusObject::checkSessionStarting(const int limit, const int tried)
|
|||
return;
|
||||
}
|
||||
|
||||
const QString output = fetchSessionInfo();
|
||||
const QString sessionMatchResult = extractRegExp(output, sessionRegExp);
|
||||
auto coro = [](WaydroidDBusObject *self, int limit, int tried) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
const QString output = co_await self->fetchSessionInfo();
|
||||
|
||||
if (!guard) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
const QString sessionMatchResult = self->extractRegExp(output, sessionRegExp);
|
||||
|
||||
if (sessionMatchResult.contains("RUNNING")) {
|
||||
m_sessionStatus = SessionRunning;
|
||||
Q_EMIT sessionStatusChanged();
|
||||
self->m_sessionStatus = SessionRunning;
|
||||
Q_EMIT self->sessionStatusChanged();
|
||||
} else if (tried == limit) {
|
||||
m_sessionStatus = SessionStopped;
|
||||
Q_EMIT sessionStatusChanged();
|
||||
self->m_sessionStatus = SessionStopped;
|
||||
Q_EMIT self->sessionStatusChanged();
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to start the session after " << tried << " tries";
|
||||
} else {
|
||||
QTimer::singleShot(500, [this, tried, limit]() {
|
||||
checkSessionStarting(limit, tried + 1);
|
||||
QTimer::singleShot(500, self, [self, tried, limit]() {
|
||||
if (self) {
|
||||
self->checkSessionStarting(limit, tried + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
coro(this, limit, tried);
|
||||
}
|
||||
|
||||
QString WaydroidDBusObject::desktopFileDirectory()
|
||||
|
|
@ -608,9 +680,16 @@ void WaydroidDBusObject::refreshApplications()
|
|||
return;
|
||||
}
|
||||
|
||||
const QString output = fetchApplicationsList();
|
||||
auto coro = [](WaydroidDBusObject *self) -> QCoro::Task<void> {
|
||||
QPointer<WaydroidDBusObject> guard(self);
|
||||
const QString output = co_await self->fetchApplicationsList();
|
||||
|
||||
if (!guard) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (output.isEmpty()) {
|
||||
return;
|
||||
co_return;
|
||||
}
|
||||
|
||||
QTextStream inFile(const_cast<QString *>(&output), QIODevice::ReadOnly);
|
||||
|
|
@ -618,8 +697,8 @@ void WaydroidDBusObject::refreshApplications()
|
|||
|
||||
// Create a map of existing applications by package name for efficient lookup
|
||||
QMap<QString, int> existingAppMap;
|
||||
for (int i = 0; i < m_applicationObjects.size(); ++i) {
|
||||
const auto &application = m_applicationObjects[i];
|
||||
for (int i = 0; i < self->m_applicationObjects.size(); ++i) {
|
||||
const auto &application = self->m_applicationObjects[i];
|
||||
existingAppMap.insert(application->packageName(), i);
|
||||
}
|
||||
|
||||
|
|
@ -650,32 +729,38 @@ void WaydroidDBusObject::refreshApplications()
|
|||
// Remove indices from end to start to avoid index shifting
|
||||
for (int i = toRemove.size() - 1; i >= 0; --i) {
|
||||
int ind = toRemove[i];
|
||||
const auto application = m_applicationObjects[ind];
|
||||
m_applicationObjects.removeAt(ind);
|
||||
Q_EMIT applicationRemoved(application->objectPath());
|
||||
const auto application = self->m_applicationObjects[ind];
|
||||
self->m_applicationObjects.removeAt(ind);
|
||||
Q_EMIT self->applicationRemoved(application->objectPath());
|
||||
application->unregisterObject();
|
||||
}
|
||||
|
||||
// Add new applications and register them
|
||||
for (const auto &application : toInsert) {
|
||||
application->registerObject();
|
||||
m_applicationObjects.append(application);
|
||||
Q_EMIT applicationAdded(application->objectPath());
|
||||
self->m_applicationObjects.append(application);
|
||||
Q_EMIT self->applicationAdded(application->objectPath());
|
||||
}
|
||||
};
|
||||
coro(this);
|
||||
}
|
||||
|
||||
QString WaydroidDBusObject::fetchApplicationsList()
|
||||
QCoro::Task<QString> WaydroidDBusObject::fetchApplicationsList()
|
||||
{
|
||||
const QStringList arguments{u"app"_s, u"list"_s};
|
||||
|
||||
auto process = QProcess(this);
|
||||
process.start(WAYDROID_COMMAND, arguments);
|
||||
process.waitForFinished();
|
||||
auto *basicProcess = new QProcess(this);
|
||||
auto process = qCoro(basicProcess);
|
||||
co_await process.start(WAYDROID_COMMAND, arguments);
|
||||
co_await process.waitForFinished();
|
||||
|
||||
if (process.exitCode() != 0) {
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to fetch applications list: " << process.readAllStandardError();
|
||||
return QString{};
|
||||
if (basicProcess->exitCode() != 0) {
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to fetch applications list: " << basicProcess->readAllStandardError();
|
||||
basicProcess->deleteLater();
|
||||
co_return QString{};
|
||||
}
|
||||
|
||||
return process.readAllStandardOutput();
|
||||
const QString output = basicProcess->readAllStandardOutput();
|
||||
basicProcess->deleteLater();
|
||||
co_return output;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "waydroidapplicationdbusobject.h"
|
||||
|
||||
#include <QCoroTask>
|
||||
#include <QDBusObjectPath>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
|
@ -145,7 +146,7 @@ private:
|
|||
|
||||
void refreshSupportsInfo();
|
||||
void refreshInstallationInfo();
|
||||
void refreshPropsInfo();
|
||||
QCoro::Task<void> refreshPropsInfo();
|
||||
|
||||
/**
|
||||
* @brief Executes the command to retrieve the current session status and related
|
||||
|
|
@ -153,7 +154,7 @@ private:
|
|||
*
|
||||
* @return A QString containing the output of the Waydroid session status command.
|
||||
*/
|
||||
QString fetchSessionInfo();
|
||||
QCoro::Task<QString> fetchSessionInfo();
|
||||
|
||||
/**
|
||||
* @brief Executes the command to retrieve the value of a specified property from the Waydroid container.
|
||||
|
|
@ -162,7 +163,7 @@ private:
|
|||
* @param defaultValue The default value to return if the property is not found or empty.
|
||||
* @return A QString containing the property value, or the defaultValue if not found.
|
||||
*/
|
||||
QString fetchPropValue(const QString key, const QString defaultValue);
|
||||
QCoro::Task<QString> fetchPropValue(const QString key, const QString defaultValue);
|
||||
|
||||
/**
|
||||
* @brief Executes the command to writes a value to a specified property in the Waydroid container.
|
||||
|
|
@ -171,7 +172,7 @@ private:
|
|||
* @param value The value to write to the property.
|
||||
* @return A boolean indicating whether the write operation was successful.
|
||||
*/
|
||||
bool writePropValue(const QString key, const QString value);
|
||||
QCoro::Task<bool> writePropValue(const QString key, const QString value);
|
||||
|
||||
/**
|
||||
* @brief Extracts text from a string using a regular expression pattern.
|
||||
|
|
@ -202,6 +203,6 @@ private:
|
|||
QString desktopFileDirectory();
|
||||
bool removeWaydroidApplications();
|
||||
|
||||
QString fetchApplicationsList();
|
||||
QCoro::Task<QString> fetchApplicationsList();
|
||||
QList<WaydroidApplicationDBusObject::Ptr> m_applicationObjects;
|
||||
};
|
||||
Loading…
Reference in a new issue