File indexing completed on 2024-11-24 04:55:02

0001 /*
0002  *   SPDX-FileCopyrightText: 2022 Jeremy Whiting <jeremy.whiting@collabora.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "SteamOSTransaction.h"
0008 #include "SteamOSResource.h"
0009 #include <KLocalizedString>
0010 #include <QDebug>
0011 #include <QTimer>
0012 #include <QtGlobal>
0013 
0014 #include "SteamOSBackend.h"
0015 #include "dbusproperties_interface.h"
0016 #include "libdiscover_steamos_debug.h"
0017 
0018 SteamOSTransaction::SteamOSTransaction(SteamOSResource *app, Transaction::Role role, ComSteampoweredAtomupd1Interface *interface)
0019     : Transaction(app->backend(), app, role, {})
0020     , m_app(app)
0021     , m_interface(interface)
0022 {
0023     setCancellable(true);
0024     setStatus(Status::SetupStatus);
0025 
0026     auto steamosProperties = new OrgFreedesktopDBusPropertiesInterface(SteamOSBackend::service(), SteamOSBackend::path(), QDBusConnection::systemBus(), this);
0027     connect(steamosProperties,
0028             &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
0029             this,
0030             [this](const QString &interface_name, const QVariantMap &changed_properties, const QStringList &invalidated_properties) {
0031                 if (interface_name != SteamOSBackend::service()) {
0032                     return;
0033                 }
0034 
0035                 auto changed = [&](const QString &property) {
0036                     return changed_properties.contains(property) || invalidated_properties.contains(property);
0037                 };
0038                 if (changed(QLatin1String("ProgressPercentage"))) {
0039                     // Get percentage and pass on to gui
0040                     double percent = m_interface->progressPercentage();
0041                     qCDebug(LIBDISCOVER_STEAMOS_LOG) << "steamos-backend: Progress percentage: " << percent;
0042                     setProgress(qBound(0.0, percent, 100.0));
0043                 }
0044                 if (changed(QLatin1String("EstimatedCompletionTime"))) {
0045                     qulonglong estimatedCompletion = m_interface->estimatedCompletionTime();
0046                     QDateTime potentialEndTime = QDateTime::fromSecsSinceEpoch(estimatedCompletion);
0047                     qCDebug(LIBDISCOVER_STEAMOS_LOG) << "steamos-backend: Estimated completion time:" << potentialEndTime.toString();
0048                     qulonglong secondsLeft = QDateTime::currentDateTimeUtc().secsTo(potentialEndTime);
0049                     qCDebug(LIBDISCOVER_STEAMOS_LOG) << "Remaining seconds:" << secondsLeft;
0050                     setRemainingTime(secondsLeft);
0051                 }
0052                 if (changed(QLatin1String("UpdateStatus"))) {
0053                     refreshStatus();
0054                 }
0055             });
0056 
0057     m_interface->StartUpdate(m_app->getBuild());
0058     refreshStatus();
0059 }
0060 
0061 void SteamOSTransaction::cancel()
0062 {
0063     if (!m_interface) {
0064         // This should never happen
0065         qWarning() << "steamos-backend: Error: No DBus interface provided to cancel. Please file a bug.";
0066         return;
0067     }
0068 
0069     m_interface->CancelUpdate();
0070 
0071     setStatus(CancelledStatus);
0072 }
0073 
0074 void SteamOSTransaction::finishTransaction()
0075 {
0076     AbstractResource::State newState;
0077     switch (role()) {
0078     case InstallRole:
0079     case ChangeAddonsRole:
0080         newState = AbstractResource::Installed;
0081         Q_EMIT needReboot();
0082         break;
0083     case RemoveRole:
0084         newState = AbstractResource::None;
0085         break;
0086     }
0087     m_app->setState(newState);
0088     setStatus(DoneStatus);
0089     deleteLater();
0090 }
0091 
0092 void SteamOSTransaction::refreshStatus()
0093 {
0094     // Get update state and update our state
0095     uint status = m_interface->updateStatus();
0096     qCDebug(LIBDISCOVER_STEAMOS_LOG) << "steamos-backend: New state: " << status;
0097 
0098     // Status is one of these from the xml definition:
0099     //    0 = IDLE, the update has not been launched yet
0100     //    1 = IN_PROGRESS, the update is currently being applied
0101     //    2 = PAUSED, the update has been paused
0102     //    3 = SUCCESSFUL, the update process successfully completed
0103     //    4 = FAILED, an error occurred during the update
0104     //    5 = CANCELLED, a special case of FAILED where the update attempt has been cancelled
0105     switch (status) {
0106     case 0: // IDLE
0107         break;
0108     case 1: // IN_PROGRESS
0109         setStatus(Status::DownloadingStatus);
0110         break;
0111     case 2: // PAUSED
0112         setStatus(Status::QueuedStatus);
0113         break;
0114     case 3: // SUCCESSFUL
0115         setStatus(Status::DoneStatus);
0116         finishTransaction();
0117         break;
0118     case 4: // FAILED
0119         setStatus(Status::DoneWithErrorStatus);
0120         finishTransaction();
0121         break;
0122     case 5: // CANCELLED
0123         setStatus(Status::CancelledStatus);
0124         finishTransaction();
0125         break;
0126     }
0127 }