File indexing completed on 2024-11-17 04:55:40
0001 /* 0002 * SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * SPDX-FileCopyrightText: 2018 Abhijeet Sharma <sharma.abhijeet2096@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "FwupdTransaction.h" 0009 #include "../DiscoverVersion.h" 0010 0011 #include <QTimer> 0012 #include <resources/AbstractBackendUpdater.h> 0013 0014 FwupdTransaction::FwupdTransaction(FwupdResource *app, FwupdBackend *backend) 0015 : Transaction(backend, app, Transaction::InstallRole, {}) 0016 , m_app(app) 0017 , m_backend(backend) 0018 { 0019 setCancellable(true); 0020 setStatus(QueuedStatus); 0021 0022 Q_ASSERT(!m_app->deviceId().isEmpty()); 0023 QTimer::singleShot(0, this, &FwupdTransaction::install); 0024 } 0025 0026 FwupdTransaction::~FwupdTransaction() = default; 0027 0028 void FwupdTransaction::install() 0029 { 0030 g_autoptr(GError) error = nullptr; 0031 0032 if (m_app->isDeviceLocked()) { 0033 QString device_id = m_app->deviceId(); 0034 if (device_id.isEmpty()) { 0035 qWarning() << "Fwupd Error: No Device ID set, cannot unlock device " << this << m_app->name(); 0036 } else if (!fwupd_client_unlock(m_backend->client, device_id.toUtf8().constData(), nullptr, &error)) { 0037 m_backend->handleError(error); 0038 } 0039 setStatus(DoneWithErrorStatus); 0040 return; 0041 } 0042 0043 const QString fileName = m_app->cacheFile(); 0044 if (!QFileInfo::exists(fileName)) { 0045 const QUrl uri(m_app->updateURI()); 0046 setStatus(DownloadingStatus); 0047 QNetworkAccessManager *manager = new QNetworkAccessManager(this); 0048 auto req = QNetworkRequest(uri); 0049 req.setHeader(QNetworkRequest::UserAgentHeader, QStringLiteral("plasma-discover/%1").arg(version)); 0050 req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); 0051 auto reply = manager->get(req); 0052 QFile *file = new QFile(fileName); 0053 if (!file->open(QFile::WriteOnly)) { 0054 qWarning() << "Fwupd Error: Could not open to write" << fileName << uri; 0055 setStatus(DoneWithErrorStatus); 0056 file->deleteLater(); 0057 return; 0058 } 0059 0060 connect(reply, &QNetworkReply::finished, this, [this, file, reply]() { 0061 file->close(); 0062 file->deleteLater(); 0063 0064 if (reply->error() != QNetworkReply::NoError) { 0065 qWarning() << "Fwupd Error: Could not download" << reply->url() << reply->errorString(); 0066 file->remove(); 0067 setStatus(DoneWithErrorStatus); 0068 } else { 0069 fwupdInstall(file->fileName()); 0070 } 0071 }); 0072 connect(reply, &QNetworkReply::readyRead, this, [file, reply]() { 0073 file->write(reply->readAll()); 0074 }); 0075 } else { 0076 fwupdInstall(fileName); 0077 } 0078 } 0079 0080 void FwupdTransaction::fwupdInstall(const QString &file) 0081 { 0082 FwupdInstallFlags install_flags = FWUPD_INSTALL_FLAG_NONE; 0083 g_autoptr(GError) error = nullptr; 0084 0085 /* only offline supported */ 0086 if (m_app->isOnlyOffline()) 0087 install_flags = static_cast<FwupdInstallFlags>(install_flags | FWUPD_INSTALL_FLAG_OFFLINE); 0088 0089 if (!fwupd_client_install(m_backend->client, m_app->deviceId().toUtf8().constData(), file.toUtf8().constData(), install_flags, nullptr, &error)) { 0090 m_backend->handleError(error); 0091 setStatus(DoneWithErrorStatus); 0092 } else 0093 finishTransaction(); 0094 } 0095 0096 void FwupdTransaction::updateProgress() 0097 { 0098 setProgress(fwupd_client_get_percentage(m_backend->client)); 0099 } 0100 0101 void FwupdTransaction::proceed() 0102 { 0103 finishTransaction(); 0104 } 0105 0106 void FwupdTransaction::cancel() 0107 { 0108 setStatus(CancelledStatus); 0109 } 0110 0111 void FwupdTransaction::finishTransaction() 0112 { 0113 AbstractResource::State newState = AbstractResource::None; 0114 switch (role()) { 0115 case InstallRole: 0116 case ChangeAddonsRole: 0117 newState = AbstractResource::Installed; 0118 break; 0119 case RemoveRole: 0120 newState = AbstractResource::None; 0121 break; 0122 } 0123 m_app->setState(newState); 0124 if (m_app->needsReboot()) { 0125 m_app->backend()->backendUpdater()->setNeedsReboot(true); 0126 } 0127 setStatus(DoneStatus); 0128 deleteLater(); 0129 }