diff --git a/libdiscover/backends/FwupdBackend/CMakeLists.txt b/libdiscover/backends/FwupdBackend/CMakeLists.txt index 2b57fae4..6dd9fa35 100644 --- a/libdiscover/backends/FwupdBackend/CMakeLists.txt +++ b/libdiscover/backends/FwupdBackend/CMakeLists.txt @@ -1,17 +1,17 @@ add_definitions( -DPROJECT_NAME=${PROJECT_NAME} -DPROJECT_VERSION=${PROJECT_VERSION}) set(fwupd-backend_SRCS FwupdResource.cpp FwupdBackend.cpp FwupdTransaction.cpp FwupdSourcesBackend.cpp ) find_package(GObject) include_directories(${LIBFWUPD_INCLUDE_DIRS}) add_library(fwupd-backend MODULE ${fwupd-backend_SRCS}) -target_link_libraries(fwupd-backend Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::ConfigCore Discover::Common LIBFWUPD ${GObject}) +target_link_libraries(fwupd-backend Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::ConfigCore Discover::Common LIBFWUPD ${GObject}) install(TARGETS fwupd-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) diff --git a/libdiscover/backends/FwupdBackend/FwupdBackend.cpp b/libdiscover/backends/FwupdBackend/FwupdBackend.cpp index 7ec5a71f..c0b977af 100644 --- a/libdiscover/backends/FwupdBackend/FwupdBackend.cpp +++ b/libdiscover/backends/FwupdBackend/FwupdBackend.cpp @@ -1,729 +1,729 @@ /*************************************************************************** * Copyright © 2013 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "FwupdBackend.h" #include "FwupdResource.h" #include "FwupdTransaction.h" #include "FwupdSourcesBackend.h" #include #include #include #include #include #include #include #include DISCOVER_BACKEND_PLUGIN(FwupdBackend) FwupdBackend::FwupdBackend(QObject* parent) : AbstractResourcesBackend(parent) , m_updater(new StandardBackendUpdater(this)) , m_fetching(true) { QTimer::singleShot(500, this, &FwupdBackend::toggleFetching); connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &FwupdBackend::updatesCountChanged); client = fwupd_client_new (); populate(QStringLiteral("Releases")); SourcesModel::global()->addSourcesBackend(new FwupdSourcesBackend(this)); } -QMap FwupdBackend::initHashMap() +QMap FwupdBackend::initHashMap() { QMap map; map.insert(G_CHECKSUM_SHA1,QCryptographicHash::Sha1); map.insert(G_CHECKSUM_SHA256,QCryptographicHash::Sha256); map.insert(G_CHECKSUM_SHA512,QCryptographicHash::Sha512); map.insert(G_CHECKSUM_MD5,QCryptographicHash::Md5); return map; } FwupdBackend::~FwupdBackend() { g_object_unref (client); } QString FwupdBackend::buildDeviceID(FwupdDevice* device) { QString DeviceID = QString::fromUtf8(fwupd_device_get_id (device)); DeviceID.replace(QLatin1Char('/'),QLatin1Char('_')); return QStringLiteral("org.fwupd.%1.device").arg(DeviceID); } void FwupdBackend::addResourceToList(FwupdResource* res) { res->setState(FwupdResource::Upgradeable); m_resources.insert(res->packageName().toLower(), res); } FwupdResource * FwupdBackend::createDevice(FwupdDevice *device) { const QString name = QString::fromUtf8(fwupd_device_get_name(device)); FwupdResource* res = new FwupdResource(name, true, this); res->setId(buildDeviceID(device)); res->addCategories(QStringLiteral("Releases")); res->setIconName(QString::fromUtf8((const gchar *)g_ptr_array_index (fwupd_device_get_icons(device),0)));// Implement a Better way to decide icon setDeviceDetails(res,device); return res; } FwupdResource * FwupdBackend::createRelease(FwupdDevice *device) { FwupdRelease *rel = fwupd_device_get_release_default (device); const QString name = QString::fromUtf8(fwupd_release_get_name(rel)); FwupdResource* res = new FwupdResource(name, true, this); res->setDeviceID(QString::fromUtf8(fwupd_device_get_id (device))); setReleaseDetails(res,rel); setDeviceDetails(res,device); if (fwupd_release_get_appstream_id (rel)) res->setId(QString::fromUtf8(fwupd_release_get_appstream_id (rel))); /* the same as we have already */ if(QLatin1Literal(fwupd_device_get_version (device)) == QLatin1Literal(fwupd_release_get_version (rel))) { qWarning() << "Fwupd Error: same firmware version as installed"; } return res; } -void FwupdBackend::setReleaseDetails(FwupdResource *res,FwupdRelease *rel) +void FwupdBackend::setReleaseDetails(FwupdResource *res, FwupdRelease *rel) { res->addCategories(QLatin1String("Releases")); if(fwupd_release_get_summary(rel)) res->setSummary(QString::fromUtf8(fwupd_release_get_summary(rel))); if(fwupd_release_get_vendor(rel)) res->setVendor(QString::fromUtf8(fwupd_release_get_vendor(rel))); if(fwupd_release_get_version(rel)) res->setVersion(QString::fromUtf8(fwupd_release_get_version(rel))); if(fwupd_release_get_description(rel)) res->setDescription(QString::fromUtf8((fwupd_release_get_description (rel)))); if(fwupd_release_get_homepage(rel)) res->setHomePage(QUrl(QString::fromUtf8(fwupd_release_get_homepage(rel)))); if(fwupd_release_get_license(rel)) res->setLicense(QString::fromUtf8(fwupd_release_get_license(rel))); if (fwupd_release_get_uri (rel)) res->m_updateURI = QString::fromUtf8(fwupd_release_get_uri (rel)); } -void FwupdBackend::setDeviceDetails(FwupdResource *res,FwupdDevice *dev) +void FwupdBackend::setDeviceDetails(FwupdResource *res, FwupdDevice *dev) { res->isLiveUpdatable = fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); res->isOnlyOffline = fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_ONLY_OFFLINE); res->needsReboot = fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT); res->isDeviceRemoval = !fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); GPtrArray *guids = fwupd_device_get_guids (dev); if(guids->len > 0) { QString guidStr = QString::fromUtf8((char *)g_ptr_array_index (guids, 0)); for (uint i = 1; i < guids->len; i++) { guidStr += QLatin1Char(',') + QString::fromUtf8((char *)g_ptr_array_index (guids, i)); } res->guidString = guidStr; } if(fwupd_device_get_name (dev)) { QString vendorName; vendorName.sprintf("%s",fwupd_device_get_name (dev)); if(vendorName.indexOf(QString::fromUtf8(fwupd_device_get_vendor (dev))) == 0) vendorName.sprintf("%s %s",fwupd_device_get_vendor (dev), fwupd_device_get_name (dev)); res->setName(vendorName); } if(fwupd_device_get_summary (dev)) res->setSummary(QString::fromUtf8(fwupd_device_get_summary(dev))); if(fwupd_device_get_vendor(dev)) res->setVendor(QString::fromUtf8(fwupd_device_get_vendor(dev))); if(fwupd_device_get_version(dev)) res->setVersion(QString::fromUtf8(fwupd_device_get_version(dev))); if(fwupd_device_get_description(dev)) res->setDescription(QString::fromUtf8((fwupd_device_get_description(dev)))); } void FwupdBackend::populate(const QString& n) { /* get devices */ g_autoptr(GPtrArray) devices = fwupd_client_get_devices (client, nullptr, nullptr); if (devices) { for (uint i = 0; i < devices->len; i++) { FwupdDevice *device = (FwupdDevice *)g_ptr_array_index (devices, i); /* Devices Which are not updatable */ if (!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)) continue; /* add releases */ FwupdResource * res = createDevice(device); res->addCategories(n); - g_autoptr(GPtrArray) releases = fwupd_client_get_releases (client,res->m_deviceID.toUtf8().constData(),nullptr,nullptr); + g_autoptr(GPtrArray) releases = fwupd_client_get_releases (client, res->m_deviceID.toUtf8().constData(), nullptr, nullptr); if (releases) { for (uint j = 0; j < releases->len; j++) { FwupdRelease *rel = (FwupdRelease *)g_ptr_array_index (releases, j); const QString name = QString::fromUtf8(fwupd_release_get_name(rel)); FwupdResource* res_ = new FwupdResource(name, true, this); setReleaseDetails (res_, rel); res->m_releases.append(res_); } } /* add all Valid Resources */ m_resources.insert(res->packageName().toLower(), res); } } } void FwupdBackend::addUpdates() { g_autoptr(GError) error = nullptr; g_autoptr(GError) error2 = nullptr; g_autoptr(GPtrArray) devices = fwupd_client_get_devices (client, nullptr, &error); if(!devices) { - if (g_error_matches (error,FWUPD_ERROR,FWUPD_ERROR_NOTHING_TO_DO)) + if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) { qDebug() << "Fwupd Info: No Devices Found"; handleError(&error); } } else{ for (uint i = 0; i < devices->len; i++) { FwupdDevice *device = (FwupdDevice *)g_ptr_array_index (devices, i); FwupdResource* res; if (!fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; /*Device is Locked Needs Unlocking*/ if (fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_LOCKED)) { res = createDevice(device); res->setIsDeviceLocked(true); addResourceToList(res); connect(res, &FwupdResource::stateChanged, this, &FwupdBackend::updatesCountChanged); continue; } - g_autoptr(GPtrArray) rels = fwupd_client_get_upgrades (client,fwupd_device_get_id(device),nullptr, &error2); + g_autoptr(GPtrArray) rels = fwupd_client_get_upgrades (client, fwupd_device_get_id(device), nullptr, &error2); if (!rels) { - if (g_error_matches (error2,FWUPD_ERROR,FWUPD_ERROR_NOTHING_TO_DO)) + if (g_error_matches (error2, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) { qWarning() << "Fwupd Error: No Packages Found for "<< fwupd_device_get_id(device); handleError(&error2); continue; } } else { - fwupd_device_add_release(device,(FwupdRelease *)g_ptr_array_index(rels,0)); + fwupd_device_add_release(device, (FwupdRelease *)g_ptr_array_index(rels, 0)); res = createApp(device); if(res == nullptr) { qWarning() << "Fwupd Error: Cannot Create App From Device"; } else { if(rels->len > 1) { QString longdescription; for(uint j = 0; j < rels->len; j++) { FwupdRelease *rel = (FwupdRelease *)g_ptr_array_index (rels, j); if (fwupd_release_get_description (rel) == nullptr) continue; longdescription += QStringLiteral("Version %1\n").arg(QString::fromUtf8(fwupd_release_get_version (rel))); longdescription += QString::fromUtf8(fwupd_release_get_description (rel)) + QLatin1Char('\n'); } res->setDescription(longdescription); } addResourceToList(res); } } } } } void FwupdBackend::addHistoricalUpdates() { g_autoptr(GError) error = nullptr; - g_autoptr(FwupdDevice) device = fwupd_client_get_results (client,FWUPD_DEVICE_ID_ANY,nullptr,&error); + g_autoptr(FwupdDevice) device = fwupd_client_get_results (client, FWUPD_DEVICE_ID_ANY, nullptr, &error); if(!device) { handleError(&error); } else { FwupdResource* res = createRelease(device); if(!res) qWarning() << "Fwupd Error: Cannot Make App for" << fwupd_device_get_id(device); else { addResourceToList(res); } } } -QByteArray FwupdBackend::getChecksum(const QUrl filename,QCryptographicHash::Algorithm hashAlgorithm) +QByteArray FwupdBackend::getChecksum(const QUrl filename, QCryptographicHash::Algorithm hashAlgorithm) { QFile f(filename.toString()); if (f.open(QFile::ReadOnly)) { QCryptographicHash hash(hashAlgorithm); if (hash.addData(&f)) { return hash.result().toHex(); } } return QByteArray(); } FwupdResource* FwupdBackend::createApp(FwupdDevice *device) { FwupdRelease *rel = fwupd_device_get_release_default (device); GPtrArray *checksums; FwupdResource* app = createRelease(device); /* update unsupported */ if (!app->isLiveUpdatable) { qWarning() << "Fwupd Error: " << app->m_name << "[" << app->m_id << "]" << "cannot be updated "; return nullptr; } /* Important Attributes missing */ if (app->m_id.isNull()) { qWarning() << "Fwupd Error: No id for firmware"; return nullptr; } if (app->m_version.isNull()) { qWarning() << "Fwupd Error: No version! for " << app->m_id; return nullptr; } if (app->m_updateVersion.isNull()) { qWarning() << "Fwupd Error: No update-version! for " << app->m_id; return nullptr; } checksums = fwupd_release_get_checksums (rel); if (checksums->len == 0) { qWarning() << "Fwupd Error: " << app->m_name << "[" << app->m_id << "]" << "(" << app->m_updateVersion << ")" "has no checksums, ignoring as unsafe"; return nullptr; } const QUrl update_uri(QString::fromUtf8(fwupd_release_get_uri(rel))); if (!update_uri.isValid()) { qWarning() << "Fwupd Error: No Update URI available for" << app->m_name << "[" << app->m_id << "]"; return nullptr; } /* Checking for firmware in the cache? */ QFileInfo basename = QFileInfo(update_uri.path()); - const QUrl filename_cache = cacheFile(QStringLiteral("fwupd"),basename); + const QUrl filename_cache = cacheFile(QStringLiteral("fwupd"), basename); if (filename_cache.isEmpty()) return nullptr; if (filename_cache.isLocalFile()) { - QByteArray checksum_tmp = QByteArray(fwupd_checksum_get_by_kind (checksums,G_CHECKSUM_SHA1)); + QByteArray checksum_tmp = QByteArray(fwupd_checksum_get_by_kind (checksums, G_CHECKSUM_SHA1)); /* Currently LVFS supports SHA1 only*/ if (checksum_tmp.isNull()) { qWarning() << "Fwupd Error: No valid checksum for" << filename_cache; } - QByteArray checksum = getChecksum(filename_cache,QCryptographicHash::Sha1); + QByteArray checksum = getChecksum(filename_cache, QCryptographicHash::Sha1); if (checksum.isNull() || checksum_tmp.isNull()) return nullptr; if (checksum_tmp != checksum) { qWarning() << "Fwupd Error: " << filename_cache << " does not match checksum, expected" << checksum_tmp << "got" << checksum; QFile::remove((filename_cache.toString())); return nullptr; } } /* link file to application and return its reference */ app->m_file = filename_cache.toString(); return app; } void FwupdBackend::saveFile(QNetworkReply *reply) { QString filename = this->m_downloadFile[reply->url()]; if (reply->error() == QNetworkReply::NoError) { QByteArray Data = reply->readAll(); QFile file(filename); if (file.open(QIODevice::WriteOnly)) { file.write(Data); } else { qWarning() << "Fwupd Error: Cannot Open File to write Data"; } file.close(); delete reply; } } bool FwupdBackend::downloadFile(const QUrl &uri,const QString &filename) { QNetworkAccessManager *manager = new QNetworkAccessManager(this); this->m_downloadFile.insert(uri,filename); QEventLoop loop; QTimer getTimer; - QTimer::connect(&getTimer,SIGNAL(timeout()),&loop, SLOT(quit())); - connect(manager, SIGNAL(finished(QNetworkReply*)),&loop, SLOT(quit())); + connect(&getTimer, &QTimer::timeout, &loop, &QEventLoop::quit); + connect(manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit); QNetworkReply *reply = manager->get(QNetworkRequest(uri)); getTimer.start(600000); // 60 Seconds TimeOout Period loop.exec(); if(!reply) { return false; } else if( QNetworkReply::NoError != reply->error() ) { return false; } else { saveFile(reply); delete manager; } return true; } bool FwupdBackend::refreshRemotes(uint cacheAge) { g_autoptr(GError) error = nullptr; - g_autoptr(GPtrArray) remotes = fwupd_client_get_remotes (client, nullptr, &error); + g_autoptr(GPtrArray) remotes = fwupd_client_get_remotes(client, nullptr, &error); if (!remotes) return false; for (uint i = 0; i < remotes->len; i++) { - FwupdRemote *remote = (FwupdRemote *)g_ptr_array_index (remotes, i); + FwupdRemote *remote = (FwupdRemote *)g_ptr_array_index(remotes, i); /*Remotes disabled by user so ignore*/ if (!fwupd_remote_get_enabled (remote)) continue; /*Local Remotes Ignore*/ if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) continue; /*Refresh the left ones*/ if (!refreshRemote(remote, cacheAge)) return false; } return true; } -bool FwupdBackend::refreshRemote(FwupdRemote* remote,uint cacheAge) +bool FwupdBackend::refreshRemote(FwupdRemote* remote, uint cacheAge) { g_autoptr(GError) error = nullptr; - if (fwupd_remote_get_filename_cache_sig (remote) == nullptr) + if (fwupd_remote_get_filename_cache_sig(remote) == nullptr) { qWarning() << "Fwupd Error: " << "Remote " << fwupd_remote_get_id (remote) << "has no cache signature!"; return false; } /* check cache age */ if (cacheAge > 0) { - quint64 age = fwupd_remote_get_age (remote); + quint64 age = fwupd_remote_get_age(remote); uint tmp = age < std::numeric_limits::max() ? (uint) age : std::numeric_limits::max(); if (tmp < cacheAge) { qDebug() << "Fwupd Info:" << fwupd_remote_get_id (remote) << "is only" << tmp << "seconds old, so ignoring refresh! "; return true; } } QString cacheId = QStringLiteral("fwupd/remotes.d/%1").arg(QString::fromUtf8(fwupd_remote_get_id (remote))); QFileInfo basenameSig = QFileInfo(QString::fromUtf8(g_path_get_basename(fwupd_remote_get_filename_cache_sig (remote)))); - const QUrl filenameSig = cacheFile(cacheId,basenameSig); + const QUrl filenameSig = cacheFile(cacheId, basenameSig); if (filenameSig.isEmpty()) return false; /* download the signature first*/ const QUrl urlSig(QString::fromUtf8(fwupd_remote_get_metadata_uri_sig(remote))); qDebug() << "Fwupd Info: downloading remotes signatures ..."; const QUrl filenameSig_(filenameSig.toString() + QStringLiteral(".tmp")); if(!downloadFile(urlSig,filenameSig_.toString())) { qDebug() << "Fwupd Info: remote signature download failed ..."; return false; } QMap map = initHashMap(); - QCryptographicHash::Algorithm hashAlgorithm = map[(fwupd_checksum_guess_kind (fwupd_remote_get_checksum (remote)))]; + QCryptographicHash::Algorithm hashAlgorithm = map[(fwupd_checksum_guess_kind(fwupd_remote_get_checksum(remote)))]; QByteArray hash = getChecksum(filenameSig_,hashAlgorithm); - if ((fwupd_remote_get_checksum (remote) == hash) && filenameSig.isLocalFile()) + if ((fwupd_remote_get_checksum(remote) == hash) && filenameSig.isLocalFile()) { qDebug() << "Fwupd Info: signature of" << urlSig.toString() << "is unchanged"; return true; } else QFile::remove(filenameSig.toString()); /* save to a file */ qDebug() << "Fwupd Info: saving new remote signature to:" << filenameSig.toString(); - if (!(QFile::copy(filenameSig_.toString(),filenameSig.toString()))) + if (!(QFile::copy(filenameSig_.toString(), filenameSig.toString()))) { QFile::remove(filenameSig_.toString()); qWarning() << "Fwupd Error: cannot save remote signature"; return false; } QFile::remove(filenameSig_.toString()); - QFileInfo basename = QFileInfo(QString::fromUtf8(g_path_get_basename (fwupd_remote_get_filename_cache (remote)))); - const QUrl filename = cacheFile(cacheId,basename); + QFileInfo basename = QFileInfo(QString::fromUtf8(g_path_get_basename(fwupd_remote_get_filename_cache(remote)))); + const QUrl filename = cacheFile(cacheId, basename); if (filename.isEmpty()) return false; - qDebug() << "Fwupd Info: saving new firmware metadata to:" << filename; + qDebug() << "Fwupd Info: saving new firmware metadata to:" << filename.toString(); - const QUrl url(QString::fromUtf8(fwupd_remote_get_metadata_uri (remote))); + const QUrl url(QString::fromUtf8(fwupd_remote_get_metadata_uri(remote))); if (!downloadFile (url, filename.toString())) { - qWarning() << "Fwupd Error: cannot download file : " << filename ; + qWarning() << "Fwupd Error: cannot download file : " << filename.toString() ; return false; } /* Sending Metadata to fwupd Daemon*/ - if (!fwupd_client_update_metadata (client,fwupd_remote_get_id (remote),filename.toString().toUtf8().constData(),filenameSig.toString().toUtf8().constData(),nullptr,&error)) + if (!fwupd_client_update_metadata (client, fwupd_remote_get_id(remote), filename.toString().toUtf8().constData(), filenameSig.toString().toUtf8().constData(), nullptr, &error)) { handleError(&error); return false; } return true; } void FwupdBackend::handleError(GError **perror) { GError *error = perror != nullptr ? *perror : nullptr; if(!error) return; switch (error->code) { case FWUPD_ERROR_ALREADY_PENDING: qWarning() << "Fwupd Error: FWUPD_ERROR_ALREADY_PENDING"; Q_EMIT passiveMessage(i18n("FWUPD ERROR ALREADY PENDING!")); break; case FWUPD_ERROR_INVALID_FILE: qWarning() << "Fwupd Error: FWUPD_ERROR_INVALID_FILE"; Q_EMIT passiveMessage(i18n("FWUPD ERROR INVALID FILE")); break; case FWUPD_ERROR_NOT_SUPPORTED: qWarning() << "Fwupd Error: FWUPD_ERROR_NOT_SUPPORTED"; Q_EMIT passiveMessage(i18n("FWUPD ERROR NOT SUPPORTED")); break; case FWUPD_ERROR_AUTH_FAILED: qWarning() << "Fwupd Error: FWUPD_ERROR_AUTH_FAILED"; Q_EMIT passiveMessage(i18n("FWUPD ERROR AUTH FAILED")); break; case FWUPD_ERROR_SIGNATURE_INVALID: qWarning() << "Fwupd Error: FWUPD_ERROR_SIGNATURE_INVALID"; Q_EMIT passiveMessage(i18n("FWUPD ERROR SIGNATURE INVALID")); break; case FWUPD_ERROR_AC_POWER_REQUIRED: qWarning() << "Fwupd Error: FWUPD_ERROR_AC_POWER_REQUIRED"; Q_EMIT passiveMessage(i18n("FWUPD ERROR AC POWER REQUIRED")); break; default: qWarning() << "Fwupd Error: Unknown Error " << error->code; break; } } const QUrl FwupdBackend::cacheFile(const QString &kind,const QFileInfo &resource) { QString basename = resource.fileName(); const QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); const QUrl cacheDirFile = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + kind); const QUrl fileUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + kind + QLatin1Char('/') + basename); if(!QFileInfo::exists(cacheDirFile.toLocalFile()) && !cacheDir.mkpath(kind)) { qWarning() << "Fwupd Error: cannot make cache directory!"; return QUrl(); } return QUrl(fileUrl.toString().remove(QStringLiteral("file://"))); } void FwupdBackend::toggleFetching() { m_fetching = !m_fetching; refreshRemotes(30*24*60*60); // Nicer Way to put time? currently 30 days in seconds addUpdates(); addHistoricalUpdates(); emit fetchingChanged(); } int FwupdBackend::updatesCount() const { return m_updater->updatesCount(); } ResultsStream* FwupdBackend::search(const AbstractResourcesBackend::Filters& filter) { QVector ret; if (!filter.resourceUrl.isEmpty() && filter.resourceUrl.scheme() == QLatin1String("fwupd")) { return findResourceByPackageName(filter.resourceUrl); } else { foreach(AbstractResource* r, m_resources) { if(r->name().contains(filter.search, Qt::CaseInsensitive) || r->comment().contains(filter.search, Qt::CaseInsensitive)) ret += r; } } return new ResultsStream(QStringLiteral("FwupdStream"), ret); } ResultsStream * FwupdBackend::findResourceByPackageName(const QUrl& search) { auto res = search.scheme() == QLatin1String("fwupd") ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' '))) : nullptr; if (!res) { return new ResultsStream(QStringLiteral("FwupdStream"), {}); } else return new ResultsStream(QStringLiteral("FwupdStream"), { res }); } AbstractBackendUpdater* FwupdBackend::backendUpdater() const { return m_updater; } AbstractReviewsBackend* FwupdBackend::reviewsBackend() const { return nullptr; } Transaction* FwupdBackend::installApplication(AbstractResource* app, const AddonList& addons) { return new FwupdTransaction(qobject_cast(app), this, addons, Transaction::InstallRole); } Transaction* FwupdBackend::installApplication(AbstractResource* app) { return new FwupdTransaction(qobject_cast(app), this, Transaction::InstallRole); } Transaction* FwupdBackend::removeApplication(AbstractResource* app) { return new FwupdTransaction(qobject_cast(app), this, Transaction::RemoveRole); } void FwupdBackend::checkForUpdates() { if(m_fetching) return; populate(QStringLiteral("Releases")); toggleFetching(); QTimer::singleShot(500, this, &FwupdBackend::toggleFetching); } AbstractResource * FwupdBackend::resourceForFile(const QUrl& path) { g_autoptr(GError) error = nullptr; QMimeDatabase db; QMimeType type = db.mimeTypeForFile(path.fileName()); FwupdResource* app = nullptr; if(type.isValid() && type.inherits(QStringLiteral("application/vnd.ms-cab-compressed"))) { g_autofree gchar *filename = path.fileName().toUtf8().data(); - g_autoptr(GPtrArray) devices = fwupd_client_get_details (client,filename,nullptr,&error); + g_autoptr(GPtrArray) devices = fwupd_client_get_details(client, filename, nullptr, &error); if (devices) { - FwupdDevice *dev = (FwupdDevice *)g_ptr_array_index (devices, 0); + FwupdDevice *dev = (FwupdDevice *)g_ptr_array_index(devices, 0); app = createRelease(dev); app->setState(AbstractResource::None); for (uint i = 1; i < devices->len; i++) { - FwupdDevice *dev = (FwupdDevice *)g_ptr_array_index (devices, i); + FwupdDevice *dev = (FwupdDevice *)g_ptr_array_index(devices, i); FwupdResource* app_ = createRelease(dev); app_->setState(AbstractResource::None); if(!app->m_releases.contains(app_)) app->m_releases.append(app_); } m_resources.insert(app->packageName(), app); addResourceToList(app); connect(app, &FwupdResource::stateChanged, this, &FwupdBackend::updatesCountChanged); } else { handleError(&error); } } return app; } QString FwupdBackend::displayName() const { return QStringLiteral("Firmware Updates"); } bool FwupdBackend::hasApplications() const { return !m_resources.isEmpty() ? true : false; } #include "FwupdBackend.moc" diff --git a/libdiscover/backends/FwupdBackend/FwupdBackend.h b/libdiscover/backends/FwupdBackend/FwupdBackend.h index d5c35d47..f5656862 100644 --- a/libdiscover/backends/FwupdBackend/FwupdBackend.h +++ b/libdiscover/backends/FwupdBackend/FwupdBackend.h @@ -1,117 +1,117 @@ /*************************************************************************** * Copyright © 2013 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifndef FWUPDBACKEND_H #define FWUPDBACKEND_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include } #include class QAction; class StandardBackendUpdater; class FwupdResource; class FwupdBackend : public AbstractResourcesBackend { Q_OBJECT Q_PROPERTY(int startElements MEMBER m_startElements) Q_ENUMS(Modes) public: explicit FwupdBackend(QObject* parent = NULL); ~FwupdBackend(); int updatesCount() const override; AbstractBackendUpdater* backendUpdater() const override; AbstractReviewsBackend* reviewsBackend() const override; ResultsStream* search(const AbstractResourcesBackend::Filters & search) override; ResultsStream * findResourceByPackageName(const QUrl& search) ; QHash resources() const { return m_resources; } bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors Transaction* installApplication(AbstractResource* app) override; Transaction* installApplication(AbstractResource* app, const AddonList& addons) override; Transaction* removeApplication(AbstractResource* app) override; bool isFetching() const override { return m_fetching; } AbstractResource * resourceForFile(const QUrl & ) override; void checkForUpdates() override; QString displayName() const override; bool hasApplications() const override; FwupdClient *client; - bool downloadFile(const QUrl &uri,const QString &filename); + bool downloadFile(const QUrl &uri, const QString &filename); bool refreshRemotes(uint cacheAge); - bool refreshRemote(FwupdRemote *remote,uint cacheAge); - const QUrl cacheFile(const QString &kind,const QFileInfo &resource); + bool refreshRemote(FwupdRemote *remote, uint cacheAge); + const QUrl cacheFile(const QString &kind, const QFileInfo &resource); FwupdResource * createDevice(FwupdDevice *device); FwupdResource * createRelease(FwupdDevice *device); FwupdResource * createApp(FwupdDevice *device); - QByteArray getChecksum(const QUrl filename,QCryptographicHash::Algorithm hashAlgorithm); + QByteArray getChecksum(const QUrl filename, QCryptographicHash::Algorithm hashAlgorithm); QString buildDeviceID(FwupdDevice* device); void addUpdates(); void addResourceToList(FwupdResource *res); void addHistoricalUpdates(); - void setReleaseDetails(FwupdResource *res,FwupdRelease *rel); - void setDeviceDetails(FwupdResource *res,FwupdDevice *device); + void setReleaseDetails(FwupdResource *res, FwupdRelease *rel); + void setDeviceDetails(FwupdResource *res, FwupdDevice *device); void handleError(GError **perror); QSet getAllUpdates(); QString getAppName(QString ID); QMap initHashMap(); public Q_SLOTS: void toggleFetching(); private Q_SLOTS: void saveFile(QNetworkReply *reply); private: void populate(const QString& name); QHash m_resources; QMap m_downloadFile; StandardBackendUpdater* m_updater; bool m_fetching; int m_startElements; QList m_toUpdate; }; #endif // FWUPDBACKEND_H diff --git a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp index 9ffc14ca..70a2cbfc 100644 --- a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp +++ b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp @@ -1,156 +1,156 @@ /*************************************************************************** * Copyright © 2014 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "FwupdSourcesBackend.h" #include #include #include class FwupdSourcesModel : public QStandardItemModel { Q_OBJECT public: FwupdSourcesModel(FwupdSourcesBackend* backend) : QStandardItemModel(backend) , m_backend(backend) {} QHash roleNames() const override { auto roles = QStandardItemModel::roleNames(); roles[Qt::CheckStateRole] = "checked"; return roles; } bool setData(const QModelIndex & index, const QVariant & value, int role) override { auto item = itemFromIndex(index); if (!item) return false; remote = fwupd_client_get_remote_by_id(m_backend->backend->client,item->data(AbstractSourcesBackend::IdRole).toString().toUtf8().constData(),nullptr,nullptr); status = fwupd_remote_get_enabled(remote); switch(role) { case Qt::CheckStateRole: { if((value.toInt() == Qt::Checked) ) { #if FWUPD_CHECK_VERSION(1,0,7) m_backend->eulaRequired(QString::fromUtf8(fwupd_remote_get_title(remote)),QString::fromUtf8(fwupd_remote_get_agreement(remote))); #endif connect(m_backend,&FwupdSourcesBackend::proceed,this, [=]() { if(fwupd_client_modify_remote(m_backend->backend->client,fwupd_remote_get_id(remote),QString(QLatin1String("Enabled")).toUtf8().constData(),(QString(QLatin1String("true")).toUtf8().constData()),nullptr,nullptr)) item->setData(value, role); } ); connect(m_backend,&FwupdSourcesBackend::cancel,this, [=]() { item->setCheckState(Qt::Unchecked); Q_EMIT dataChanged(index,index,{}); return false; } ); } else if(value.toInt() == Qt::Unchecked) { if(fwupd_client_modify_remote(m_backend->backend->client,fwupd_remote_get_id(remote),QString(QLatin1String("Enabled")).toUtf8().constData(),(QString(QLatin1String("false")).toUtf8().constData()),nullptr,nullptr)) item->setData(value, role); } } } Q_EMIT dataChanged(index,index,{}); return true; } private: FwupdSourcesBackend* m_backend; FwupdRemote* remote; bool status; }; FwupdSourcesBackend::FwupdSourcesBackend(AbstractResourcesBackend * parent) : AbstractSourcesBackend(parent) , backend(qobject_cast(parent)) , m_sources(new FwupdSourcesModel(this)) { populateSources(); } void FwupdSourcesBackend::populateSources() { /* find all remotes */ g_autoptr(GPtrArray) remotes = fwupd_client_get_remotes (backend->client,nullptr,nullptr); if(remotes != nullptr) { for (uint i = 0; i < remotes->len; i++) { FwupdRemote *remote = (FwupdRemote *)g_ptr_array_index (remotes, i); if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) continue; const QString id = QString::fromUtf8(fwupd_remote_get_id (remote)); if (id.isEmpty()) continue; bool status = !fwupd_remote_get_enabled(remote); QStandardItem* it = new QStandardItem(id); it->setData(id, AbstractSourcesBackend::IdRole); it->setData(QVariant(QString::fromUtf8(fwupd_remote_get_title (remote))), Qt::ToolTipRole); it->setCheckable(true); it->setCheckState(status ? Qt::Unchecked : Qt::Checked); m_sources->appendRow(it); } } } QAbstractItemModel* FwupdSourcesBackend::sources() { return m_sources; } -void FwupdSourcesBackend::eulaRequired( const QString& remoteName , const QString& licenseAgreement) +void FwupdSourcesBackend::eulaRequired( const QString& remoteName, const QString& licenseAgreement) { Q_EMIT proceedRequest(i18n("Accept EULA"), i18n("The remote %1 require that you accept their license:\n %2", remoteName, licenseAgreement)); } bool FwupdSourcesBackend::addSource(const QString& id) { qWarning() << "Fwupd Error: Custom Addition of Sources Not Allowed" << "Remote-ID" << id; return false; } bool FwupdSourcesBackend::removeSource(const QString& id) { qWarning() << "Fwupd Error: Removal of Sources Not Allowed" << "Remote-ID" << id; return false; } QList FwupdSourcesBackend::actions() const { - return m_actions ; + return {} ; } #include "FwupdSourcesBackend.moc" diff --git a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h index 9cc47ea2..e3b01980 100644 --- a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h +++ b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h @@ -1,57 +1,56 @@ /*************************************************************************** * Copyright © 2014 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifndef FWUPDSOURCESBACKEND_H #define FWUPDSOURCESBACKEND_H #include #include "FwupdBackend.h" #include #include "FwupdBackend.h" class FwupdSourcesModel; class FwupdSourcesBackend : public AbstractSourcesBackend { Q_OBJECT public: explicit FwupdSourcesBackend(AbstractResourcesBackend * parent); FwupdBackend* backend ; QAbstractItemModel* sources() override; bool addSource(const QString& id) override; bool removeSource(const QString& id) override; QString idDescription() override { return QString(); } QList actions() const override; bool supportsAdding() const override { return false; } - void eulaRequired(const QString& remoteName , const QString& licenseAgreement); + void eulaRequired(const QString& remoteName, const QString& licenseAgreement); void populateSources(); Q_SIGNALS: void proceed() override; void cancel() override; private: FwupdSourcesModel* m_sources; - QList m_actions; }; #endif // FWUPDSOURCESBACKEND_H diff --git a/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp b/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp index 3eef2213..cb60fd6e 100644 --- a/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp +++ b/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp @@ -1,201 +1,200 @@ /*************************************************************************** * Copyright © 2013 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "FwupdTransaction.h" #include FwupdTransaction::FwupdTransaction(FwupdResource* app, FwupdBackend* backend, Role role) : FwupdTransaction(app, backend,{}, role) { } FwupdTransaction::FwupdTransaction(FwupdResource* app, FwupdBackend* backend, const AddonList& addons, Transaction::Role role) : Transaction(app->backend(), app, role, addons) , m_app(app) , m_backend(backend) { setCancellable(true); if(role == InstallRole) { setStatus(QueuedStatus); if(!check()) qWarning() << "Fwupd Error: Error In Install!"; } else if(role == RemoveRole) { if(!remove()) qWarning() << "Fwupd Error: Error in Remove!"; } - - iterateTransaction(); } FwupdTransaction::~FwupdTransaction() { } bool FwupdTransaction::check() { g_autoptr(GError) error = nullptr; if(m_app->isDeviceLocked) { QString device_id = m_app->m_deviceID; if(device_id.isNull()) { qWarning("Fwupd Error: No Device ID set, cannot unlock device "); return false; } if (!fwupd_client_unlock (m_backend->client, device_id.toUtf8().constData(),nullptr, &error)) { m_backend->handleError(&error); return false; } return true; } if(!install()) { qWarning("Fwupd Error: Cannot Install Application"); return false; } return true; } bool FwupdTransaction::install() { QString localFile = m_app->m_file; if(localFile.isEmpty()) { qWarning("Fwupd Error: No Local File Set For this Resource"); return false; } if (!(QFileInfo::exists(localFile))) { const QUrl uri(m_app->m_updateURI); setStatus(DownloadingStatus); QNetworkAccessManager *manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(fwupdInstall(QNetworkReply*))); + connect(manager, &QNetworkAccessManager::finished,this, [this](QNetworkReply* reply){fwupdInstall(reply);}); manager->get(QNetworkRequest(uri)); } else { fwupdInstall(nullptr); } return true; } void FwupdTransaction::fwupdInstall(QNetworkReply* reply) { if(reply) { QString filename = m_app->m_file; if (reply->error() == QNetworkReply::NoError) { QByteArray Data = reply->readAll(); QFile file(filename); if (file.open(QIODevice::WriteOnly)) { file.write(Data); } else { qWarning() << "Fwupd Error: Cannot Save File"; } file.close(); delete reply; } } FwupdInstallFlags install_flags = FWUPD_INSTALL_FLAG_NONE; g_autoptr(GError) error = nullptr; QString localFile = m_app->m_file; QString deviceId = m_app->m_deviceID; /* limit to single device? */ if (deviceId.isNull()) deviceId = QStringLiteral(FWUPD_DEVICE_ID_ANY); /* only offline supported */ if (m_app->isOnlyOffline) install_flags = static_cast(install_flags | FWUPD_INSTALL_FLAG_OFFLINE); m_iterate = true; - QTimer::singleShot(100, this, &FwupdTransaction::iterateTransaction); - if (!fwupd_client_install (m_backend->client, deviceId.toUtf8().constData(),localFile.toUtf8().constData(), install_flags,nullptr, &error)) + QTimer::singleShot(100, this, &FwupdTransaction::updateProgress); + if (!fwupd_client_install (m_backend->client, deviceId.toUtf8().constData(), localFile.toUtf8().constData(), install_flags, nullptr, &error)) { m_backend->handleError(&error); m_iterate = false; return; } + m_iterate = false; finishTransaction(); } bool FwupdTransaction::remove() { m_app->setState(AbstractResource::State::None); return true; } -void FwupdTransaction::iterateTransaction() +void FwupdTransaction::updateProgress() { if (!m_iterate) return; setStatus(CommittingStatus); if(progress()<100) { setProgress(fwupd_client_get_percentage (m_backend->client)); - QTimer::singleShot(100, this, &FwupdTransaction::iterateTransaction); + QTimer::singleShot(100, this, &FwupdTransaction::updateProgress); } } void FwupdTransaction::proceed() { finishTransaction(); } void FwupdTransaction::cancel() { m_iterate = false; setStatus(CancelledStatus); } void FwupdTransaction::finishTransaction() { AbstractResource::State newState; switch(role()) { case InstallRole: case ChangeAddonsRole: newState = AbstractResource::Installed; break; case RemoveRole: newState = AbstractResource::None; break; } m_app->setAddons(addons()); m_app->setState(newState); setStatus(DoneStatus); deleteLater(); } diff --git a/libdiscover/backends/FwupdBackend/FwupdTransaction.h b/libdiscover/backends/FwupdBackend/FwupdTransaction.h index ef6b368e..426a9a9d 100644 --- a/libdiscover/backends/FwupdBackend/FwupdTransaction.h +++ b/libdiscover/backends/FwupdBackend/FwupdTransaction.h @@ -1,55 +1,55 @@ /*************************************************************************** * Copyright © 2013 Aleix Pol Gonzalez * * Copyright © 2018 Abhijeet Sharma * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifndef FWUPDTRANSACTION_H #define FWUPDTRANSACTION_H #include #include "FwupdBackend.h" #include "FwupdResource.h" class FwupdResource; class FwupdTransaction : public Transaction { Q_OBJECT public: FwupdTransaction(FwupdResource* app, FwupdBackend* backend, Role role); FwupdTransaction(FwupdResource* app, FwupdBackend* backend, const AddonList& list, Role role); ~FwupdTransaction(); bool check(); bool install(); bool remove(); void cancel() override; void proceed() override; private Q_SLOTS: - void iterateTransaction(); + void updateProgress(); void finishTransaction(); void fwupdInstall(QNetworkReply* reply); private: bool m_iterate = true; FwupdResource* m_app; FwupdBackend* m_backend; }; #endif // FWUPDTRANSACTION_H