Changeset View
Changeset View
Standalone View
Standalone View
libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
Show All 15 Lines | |||||
16 | * GNU General Public License for more details. * | 16 | * GNU General Public License for more details. * | ||
17 | * * | 17 | * * | ||
18 | * You should have received a copy of the GNU General Public License * | 18 | * You should have received a copy of the GNU General Public License * | ||
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
20 | ***************************************************************************/ | 20 | ***************************************************************************/ | ||
21 | 21 | | |||
22 | #include "FlatpakBackend.h" | 22 | #include "FlatpakBackend.h" | ||
23 | #include "FlatpakFetchDataJob.h" | 23 | #include "FlatpakFetchDataJob.h" | ||
24 | #include "FlatpakFetchUpdatesJob.h" | | |||
25 | #include "FlatpakResource.h" | 24 | #include "FlatpakResource.h" | ||
26 | #include "FlatpakSourcesBackend.h" | 25 | #include "FlatpakSourcesBackend.h" | ||
27 | #include "FlatpakTransaction.h" | 26 | #include "FlatpakTransaction.h" | ||
28 | 27 | | |||
29 | #include <resources/StandardBackendUpdater.h> | 28 | #include <resources/StandardBackendUpdater.h> | ||
30 | #include <resources/SourcesModel.h> | 29 | #include <resources/SourcesModel.h> | ||
31 | #include <Transaction/Transaction.h> | 30 | #include <Transaction/Transaction.h> | ||
32 | #include <appstream/OdrsReviewsBackend.h> | 31 | #include <appstream/OdrsReviewsBackend.h> | ||
33 | #include <appstream/AppStreamIntegration.h> | 32 | #include <appstream/AppStreamIntegration.h> | ||
34 | 33 | | |||
35 | #include <AppStreamQt/bundle.h> | 34 | #include <AppStreamQt/bundle.h> | ||
36 | #include <AppStreamQt/component.h> | 35 | #include <AppStreamQt/component.h> | ||
37 | #include <AppStreamQt/icon.h> | 36 | #include <AppStreamQt/icon.h> | ||
38 | #include <AppStreamQt/metadata.h> | 37 | #include <AppStreamQt/metadata.h> | ||
39 | 38 | | |||
40 | #include <KAboutData> | 39 | #include <KAboutData> | ||
41 | #include <KLocalizedString> | 40 | #include <KLocalizedString> | ||
42 | #include <KPluginFactory> | 41 | #include <KPluginFactory> | ||
43 | #include <KConfigGroup> | 42 | #include <KConfigGroup> | ||
44 | #include <KSharedConfig> | 43 | #include <KSharedConfig> | ||
45 | 44 | | |||
46 | #include <QAction> | 45 | #include <QAction> | ||
46 | #include <QtConcurrentRun> | ||||
47 | #include <QDebug> | 47 | #include <QDebug> | ||
48 | #include <QDir> | 48 | #include <QDir> | ||
49 | #include <QFile> | 49 | #include <QFile> | ||
50 | #include <QFutureWatcher> | ||||
50 | #include <QMessageBox> | 51 | #include <QMessageBox> | ||
51 | #include <QSettings> | 52 | #include <QSettings> | ||
52 | #include <QThread> | 53 | #include <QThread> | ||
53 | #include <QTimer> | 54 | #include <QTimer> | ||
54 | #include <QTextStream> | 55 | #include <QTextStream> | ||
55 | #include <QTemporaryFile> | 56 | #include <QTemporaryFile> | ||
56 | #include <QNetworkAccessManager> | 57 | #include <QNetworkAccessManager> | ||
57 | 58 | | |||
58 | #include <glib.h> | 59 | #include <glib.h> | ||
59 | 60 | | |||
60 | MUON_BACKEND_PLUGIN(FlatpakBackend) | 61 | MUON_BACKEND_PLUGIN(FlatpakBackend) | ||
61 | 62 | | |||
62 | FlatpakBackend::FlatpakBackend(QObject* parent) | 63 | FlatpakBackend::FlatpakBackend(QObject* parent) | ||
63 | : AbstractResourcesBackend(parent) | 64 | : AbstractResourcesBackend(parent) | ||
64 | , m_updater(new StandardBackendUpdater(this)) | 65 | , m_updater(new StandardBackendUpdater(this)) | ||
65 | , m_reviews(AppStreamIntegration::global()->reviews()) | 66 | , m_reviews(AppStreamIntegration::global()->reviews()) | ||
66 | , m_fetching(false) | 67 | , m_fetching(false) | ||
68 | , m_threadPool(new QThreadPool(this)) | ||||
67 | { | 69 | { | ||
68 | g_autoptr(GError) error = nullptr; | 70 | g_autoptr(GError) error = nullptr; | ||
69 | m_cancellable = g_cancellable_new(); | 71 | m_cancellable = g_cancellable_new(); | ||
70 | 72 | | |||
71 | connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &FlatpakBackend::updatesCountChanged); | 73 | connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &FlatpakBackend::updatesCountChanged); | ||
72 | 74 | | |||
73 | // Load flatpak installation | 75 | // Load flatpak installation | ||
74 | if (!setupFlatpakInstallations(&error)) { | 76 | if (!setupFlatpakInstallations(&error)) { | ||
75 | qWarning() << "Failed to setup flatpak installations:" << error->message; | 77 | qWarning() << "Failed to setup flatpak installations:" << error->message; | ||
76 | } else { | 78 | } else { | ||
77 | reloadPackageList(); | 79 | reloadPackageList(); | ||
78 | 80 | | |||
79 | checkForUpdates(); | 81 | checkForUpdates(); | ||
80 | 82 | | |||
81 | m_sources = new FlatpakSourcesBackend(m_installations, this); | 83 | m_sources = new FlatpakSourcesBackend(m_installations, this); | ||
82 | SourcesModel::global()->addSourcesBackend(m_sources); | 84 | SourcesModel::global()->addSourcesBackend(m_sources); | ||
83 | } | 85 | } | ||
84 | 86 | | |||
85 | connect(m_reviews.data(), &OdrsReviewsBackend::ratingsReady, this, &FlatpakBackend::announceRatingsReady); | 87 | connect(m_reviews.data(), &OdrsReviewsBackend::ratingsReady, this, &FlatpakBackend::announceRatingsReady); | ||
86 | } | 88 | } | ||
87 | 89 | | |||
88 | FlatpakBackend::~FlatpakBackend() | 90 | FlatpakBackend::~FlatpakBackend() | ||
89 | { | 91 | { | ||
92 | m_threadPool.clear(); | ||||
90 | for(auto inst : m_installations) | 93 | for(auto inst : m_installations) | ||
91 | g_object_unref(inst); | 94 | g_object_unref(inst); | ||
92 | 95 | | |||
93 | g_object_unref(m_cancellable); | 96 | g_object_unref(m_cancellable); | ||
94 | } | 97 | } | ||
95 | 98 | | |||
96 | bool FlatpakBackend::isValid() const | 99 | bool FlatpakBackend::isValid() const | ||
97 | { | 100 | { | ||
▲ Show 20 Lines • Show All 308 Lines • ▼ Show 20 Line(s) | 368 | { | |||
406 | 409 | | |||
407 | auto resource = new FlatpakResource(asComponent, preferredInstallation(), this); | 410 | auto resource = new FlatpakResource(asComponent, preferredInstallation(), this); | ||
408 | resource->setFlatpakFileType(QStringLiteral("flatpakref")); | 411 | resource->setFlatpakFileType(QStringLiteral("flatpakref")); | ||
409 | resource->setOrigin(QString::fromUtf8(remoteName)); | 412 | resource->setOrigin(QString::fromUtf8(remoteName)); | ||
410 | resource->updateFromRef(ref); | 413 | resource->updateFromRef(ref); | ||
411 | 414 | | |||
412 | QUrl runtimeUrl = QUrl(settings.value(QStringLiteral("Flatpak Ref/RuntimeRepo")).toString()); | 415 | QUrl runtimeUrl = QUrl(settings.value(QStringLiteral("Flatpak Ref/RuntimeRepo")).toString()); | ||
413 | if (!runtimeUrl.isEmpty()) { | 416 | if (!runtimeUrl.isEmpty()) { | ||
417 | auto installation = preferredInstallation(); | ||||
414 | // We need to fetch metadata to find information about required runtime | 418 | // We need to fetch metadata to find information about required runtime | ||
415 | FlatpakFetchDataJob *job = new FlatpakFetchDataJob(preferredInstallation(), resource, FlatpakFetchDataJob::FetchMetadata); | 419 | auto fw = new QFutureWatcher<QByteArray>(this); | ||
416 | connect(job, &FlatpakFetchDataJob::finished, job, &FlatpakFetchDataJob::deleteLater); | 420 | fw->setFuture(QtConcurrent::run(&m_threadPool, &FlatpakRunnables::fetchMetadata, installation, resource)); | ||
417 | connect(job, &FlatpakFetchDataJob::jobFetchMetadataFailed, this, [this, resource] { | 421 | connect(fw, &QFutureWatcher<QByteArray>::finished, this, [this, installation, resource, fw, runtimeUrl]() { | ||
422 | const auto metadata = fw->result(); | ||||
418 | // Even when we failed to fetch information about runtime we still want to show the application | 423 | // Even when we failed to fetch information about runtime we still want to show the application | ||
419 | addResource(resource); | 424 | if (metadata.isEmpty()) { | ||
420 | }); | 425 | onFetchMetadataFinished(installation, resource, metadata); | ||
421 | connect(job, &FlatpakFetchDataJob::jobFetchMetadataFinished, this, [this, runtimeUrl] (FlatpakInstallation *installation, FlatpakResource *resource, const QByteArray &metadata) { | 426 | } else { | ||
422 | Q_UNUSED(installation); | | |||
423 | | ||||
424 | updateAppMetadata(resource, metadata); | 427 | updateAppMetadata(resource, metadata); | ||
425 | 428 | | |||
426 | auto runtime = getRuntimeForApp(resource); | 429 | auto runtime = getRuntimeForApp(resource); | ||
427 | if (!runtime || (runtime && !runtime->isInstalled())) { | 430 | if (!runtime || (runtime && !runtime->isInstalled())) { | ||
428 | FlatpakFetchRemoteResourceJob *fetchRemoteResource = new FlatpakFetchRemoteResourceJob(runtimeUrl, this); | 431 | FlatpakFetchRemoteResourceJob *fetchRemoteResource = new FlatpakFetchRemoteResourceJob(runtimeUrl, this); | ||
429 | connect(fetchRemoteResource, &FlatpakFetchRemoteResourceJob::jobFinished, this, [this, resource] (bool success, FlatpakResource *repoResource) { | 432 | connect(fetchRemoteResource, &FlatpakFetchRemoteResourceJob::jobFinished, this, [this, resource] (bool success, FlatpakResource *repoResource) { | ||
430 | if (success) { | 433 | if (success) { | ||
431 | installApplication(repoResource); | 434 | installApplication(repoResource); | ||
432 | } | 435 | } | ||
433 | addResource(resource); | 436 | addResource(resource); | ||
434 | }); | 437 | }); | ||
435 | fetchRemoteResource->start(); | 438 | fetchRemoteResource->start(); | ||
436 | return; | 439 | return; | ||
437 | } else { | 440 | } else { | ||
438 | addResource(resource); | 441 | addResource(resource); | ||
439 | } | 442 | } | ||
443 | } | ||||
444 | fw->deleteLater(); | ||||
440 | }); | 445 | }); | ||
441 | job->start(); | | |||
442 | } else { | 446 | } else { | ||
443 | addResource(resource); | 447 | addResource(resource); | ||
444 | } | 448 | } | ||
445 | 449 | | |||
446 | return resource; | 450 | return resource; | ||
447 | } | 451 | } | ||
448 | 452 | | |||
449 | FlatpakResource * FlatpakBackend::addSourceFromFlatpakRepo(const QUrl &url) | 453 | FlatpakResource * FlatpakBackend::addSourceFromFlatpakRepo(const QUrl &url) | ||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Line(s) | 707 | for (uint i = 0; i < refs->len; i++) { | |||
718 | FlatpakResource *resource = getAppForInstalledRef(flatpakInstallation, ref); | 722 | FlatpakResource *resource = getAppForInstalledRef(flatpakInstallation, ref); | ||
719 | if (resource) { | 723 | if (resource) { | ||
720 | resource->setState(AbstractResource::Upgradeable); | 724 | resource->setState(AbstractResource::Upgradeable); | ||
721 | updateAppSize(flatpakInstallation, resource); | 725 | updateAppSize(flatpakInstallation, resource); | ||
722 | } | 726 | } | ||
723 | } | 727 | } | ||
724 | } | 728 | } | ||
725 | 729 | | |||
726 | void FlatpakBackend::loadRemoteUpdates(FlatpakInstallation *flatpakInstallation) | 730 | void FlatpakBackend::loadRemoteUpdates(FlatpakInstallation* installation) | ||
727 | { | 731 | { | ||
728 | FlatpakFetchUpdatesJob *job = new FlatpakFetchUpdatesJob(flatpakInstallation); | 732 | auto fw = new QFutureWatcher<GPtrArray *>(this); | ||
729 | connect(job, &FlatpakFetchUpdatesJob::finished, job, &FlatpakFetchUpdatesJob::deleteLater); | 733 | fw->setFuture(QtConcurrent::run(&m_threadPool, [installation]() -> GPtrArray * { | ||
730 | connect(job, &FlatpakFetchUpdatesJob::jobFetchUpdatesFinished, this, &FlatpakBackend::onFetchUpdatesFinished); | 734 | g_autoptr(GCancellable) cancellable = g_cancellable_new(); | ||
731 | job->start(); | 735 | g_autoptr(GError) localError = nullptr; | ||
736 | GPtrArray *refs = flatpak_installation_list_installed_refs_for_update(installation, cancellable, &localError); | ||||
737 | if (!refs) { | ||||
738 | qWarning() << "Failed to get list of installed refs for listing updates: " << localError->message; | ||||
739 | } | ||||
740 | return refs; | ||||
741 | })); | ||||
742 | connect(fw, &QFutureWatcher<GPtrArray *>::finished, this, [this, installation, fw](){ | ||||
743 | auto refs = fw->result(); | ||||
744 | onFetchUpdatesFinished(installation, refs); | ||||
745 | fw->deleteLater(); | ||||
746 | }); | ||||
732 | } | 747 | } | ||
733 | 748 | | |||
734 | void FlatpakBackend::onFetchUpdatesFinished(FlatpakInstallation *flatpakInstallation, GPtrArray *updates) | 749 | void FlatpakBackend::onFetchUpdatesFinished(FlatpakInstallation *flatpakInstallation, GPtrArray *updates) | ||
735 | { | 750 | { | ||
736 | g_autoptr(GPtrArray) fetchedUpdates = updates; | 751 | g_autoptr(GPtrArray) fetchedUpdates = updates; | ||
737 | 752 | | |||
738 | for (uint i = 0; i < fetchedUpdates->len; i++) { | 753 | for (uint i = 0; i < fetchedUpdates->len; i++) { | ||
739 | FlatpakInstalledRef *ref = FLATPAK_INSTALLED_REF(g_ptr_array_index(fetchedUpdates, i)); | 754 | FlatpakInstalledRef *ref = FLATPAK_INSTALLED_REF(g_ptr_array_index(fetchedUpdates, i)); | ||
Show All 26 Lines | |||||
766 | } | 781 | } | ||
767 | 782 | | |||
768 | class FlatpakRefreshAppstreamMetadataJob : public QThread | 783 | class FlatpakRefreshAppstreamMetadataJob : public QThread | ||
769 | { | 784 | { | ||
770 | Q_OBJECT | 785 | Q_OBJECT | ||
771 | public: | 786 | public: | ||
772 | FlatpakRefreshAppstreamMetadataJob(FlatpakInstallation *installation, FlatpakRemote *remote) | 787 | FlatpakRefreshAppstreamMetadataJob(FlatpakInstallation *installation, FlatpakRemote *remote) | ||
773 | : QThread() | 788 | : QThread() | ||
789 | , m_cancellable(g_cancellable_new()) | ||||
774 | , m_installation(installation) | 790 | , m_installation(installation) | ||
775 | , m_remote(remote) | 791 | , m_remote(remote) | ||
776 | { | 792 | { | ||
777 | m_cancellable = g_cancellable_new(); | 793 | connect(this, &FlatpakRefreshAppstreamMetadataJob::finished, this, &QObject::deleteLater); | ||
778 | } | 794 | } | ||
779 | 795 | | |||
780 | ~FlatpakRefreshAppstreamMetadataJob() | 796 | ~FlatpakRefreshAppstreamMetadataJob() | ||
781 | { | 797 | { | ||
782 | g_object_unref(m_cancellable); | 798 | g_object_unref(m_cancellable); | ||
783 | } | 799 | } | ||
784 | 800 | | |||
785 | void cancel() | 801 | void cancel() | ||
Show All 27 Lines | 828 | private: | |||
813 | GCancellable *m_cancellable; | 829 | GCancellable *m_cancellable; | ||
814 | FlatpakInstallation *m_installation; | 830 | FlatpakInstallation *m_installation; | ||
815 | FlatpakRemote *m_remote; | 831 | FlatpakRemote *m_remote; | ||
816 | }; | 832 | }; | ||
817 | 833 | | |||
818 | void FlatpakBackend::refreshAppstreamMetadata(FlatpakInstallation *installation, FlatpakRemote *remote) | 834 | void FlatpakBackend::refreshAppstreamMetadata(FlatpakInstallation *installation, FlatpakRemote *remote) | ||
819 | { | 835 | { | ||
820 | FlatpakRefreshAppstreamMetadataJob *job = new FlatpakRefreshAppstreamMetadataJob(installation, remote); | 836 | FlatpakRefreshAppstreamMetadataJob *job = new FlatpakRefreshAppstreamMetadataJob(installation, remote); | ||
821 | connect(job, &FlatpakRefreshAppstreamMetadataJob::finished, job, &FlatpakFetchDataJob::deleteLater); | | |||
822 | connect(job, &FlatpakRefreshAppstreamMetadataJob::jobRefreshAppstreamMetadataFinished, this, &FlatpakBackend::integrateRemote); | 837 | connect(job, &FlatpakRefreshAppstreamMetadataJob::jobRefreshAppstreamMetadataFinished, this, &FlatpakBackend::integrateRemote); | ||
823 | job->start(); | 838 | job->start(); | ||
824 | } | 839 | } | ||
825 | 840 | | |||
826 | void FlatpakBackend::reloadPackageList() | 841 | void FlatpakBackend::reloadPackageList() | ||
827 | { | 842 | { | ||
828 | setFetching(true); | 843 | setFetching(true); | ||
829 | 844 | | |||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | 888 | { | |||
879 | } | 894 | } | ||
880 | 895 | | |||
881 | installationPath = flatpak_installation_get_path(flatpakInstallation); | 896 | installationPath = flatpak_installation_get_path(flatpakInstallation); | ||
882 | const QString path = QString::fromUtf8(g_file_get_path(installationPath)) + QStringLiteral("/app/%1/%2/%3/active/metadata").arg(resource->flatpakName()).arg(resource->arch()).arg(resource->branch()); | 897 | const QString path = QString::fromUtf8(g_file_get_path(installationPath)) + QStringLiteral("/app/%1/%2/%3/active/metadata").arg(resource->flatpakName()).arg(resource->arch()).arg(resource->branch()); | ||
883 | 898 | | |||
884 | if (QFile::exists(path)) { | 899 | if (QFile::exists(path)) { | ||
885 | return updateAppMetadata(resource, path); | 900 | return updateAppMetadata(resource, path); | ||
886 | } else { | 901 | } else { | ||
887 | FlatpakFetchDataJob *job = new FlatpakFetchDataJob(flatpakInstallation, resource, FlatpakFetchDataJob::FetchMetadata); | 902 | auto fw = new QFutureWatcher<QByteArray>(this); | ||
888 | connect(job, &FlatpakFetchDataJob::finished, job, &FlatpakFetchDataJob::deleteLater); | 903 | fw->setFuture(QtConcurrent::run(&m_threadPool, &FlatpakRunnables::fetchMetadata, flatpakInstallation, resource)); | ||
889 | connect(job, &FlatpakFetchDataJob::jobFetchMetadataFinished, this, &FlatpakBackend::onFetchMetadataFinished); | 904 | connect(fw, &QFutureWatcher<QByteArray>::finished, this, [this, flatpakInstallation, resource, fw]() { | ||
890 | job->start(); | 905 | const auto metadata = fw->result(); | ||
906 | if (!metadata.isEmpty()) | ||||
907 | onFetchMetadataFinished(flatpakInstallation, resource, metadata); | ||||
908 | fw->deleteLater(); | ||||
909 | }); | ||||
910 | | ||||
891 | // Return false to indicate we cannot continue (right now used only in updateAppSize()) | 911 | // Return false to indicate we cannot continue (right now used only in updateAppSize()) | ||
892 | return false; | 912 | return false; | ||
893 | } | 913 | } | ||
894 | } | 914 | } | ||
895 | 915 | | |||
896 | void FlatpakBackend::onFetchMetadataFinished(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource, const QByteArray &metadata) | 916 | void FlatpakBackend::onFetchMetadataFinished(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource, const QByteArray &metadata) | ||
897 | { | 917 | { | ||
898 | updateAppMetadata(resource, metadata); | 918 | updateAppMetadata(resource, metadata); | ||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Line(s) | 1005 | if (resource->state() == AbstractResource::Installed) { | |||
991 | } | 1011 | } | ||
992 | resource->setInstalledSize(flatpak_installed_ref_get_installed_size(ref)); | 1012 | resource->setInstalledSize(flatpak_installed_ref_get_installed_size(ref)); | ||
993 | } else { | 1013 | } else { | ||
994 | if (resource->origin().isEmpty()) { | 1014 | if (resource->origin().isEmpty()) { | ||
995 | qWarning() << "Failed to get size of" << resource->name() << " because of missing origin"; | 1015 | qWarning() << "Failed to get size of" << resource->name() << " because of missing origin"; | ||
996 | return false; | 1016 | return false; | ||
997 | } | 1017 | } | ||
998 | 1018 | | |||
999 | FlatpakFetchDataJob *job = new FlatpakFetchDataJob(flatpakInstallation, resource, FlatpakFetchDataJob::FetchSize); | 1019 | auto futureWatcher = new QFutureWatcher<FlatpakRunnables::SizeInformation>(this); | ||
1000 | connect(job, &FlatpakFetchDataJob::finished, job, &FlatpakFetchDataJob::deleteLater); | 1020 | futureWatcher->setFuture(QtConcurrent::run(&m_threadPool, &FlatpakRunnables::fetchFlatpakSize, flatpakInstallation, resource)); | ||
1001 | connect(job, &FlatpakFetchDataJob::jobFetchSizeFinished, this, &FlatpakBackend::onFetchSizeFinished); | 1021 | connect(futureWatcher, &QFutureWatcher<FlatpakRunnables::SizeInformation>::finished, this, [this, resource, futureWatcher]() { | ||
1002 | connect(job, &FlatpakFetchDataJob::jobFetchSizeFailed, [resource] () { | 1022 | auto value = futureWatcher->result(); | ||
1023 | if (value.valid) { | ||||
1024 | onFetchSizeFinished(resource, value.downloadSize, value.installedSize); | ||||
1025 | } else { | ||||
1003 | resource->setPropertyState(FlatpakResource::DownloadSize, FlatpakResource::UnknownOrFailed); | 1026 | resource->setPropertyState(FlatpakResource::DownloadSize, FlatpakResource::UnknownOrFailed); | ||
1004 | resource->setPropertyState(FlatpakResource::InstalledSize, FlatpakResource::UnknownOrFailed); | 1027 | resource->setPropertyState(FlatpakResource::InstalledSize, FlatpakResource::UnknownOrFailed); | ||
1028 | } | ||||
1029 | futureWatcher->deleteLater(); | ||||
1005 | }); | 1030 | }); | ||
1006 | job->start(); | | |||
1007 | } | 1031 | } | ||
1008 | 1032 | | |||
1009 | return true; | 1033 | return true; | ||
1010 | } | 1034 | } | ||
1011 | 1035 | | |||
1012 | void FlatpakBackend::onFetchSizeFinished(FlatpakResource *resource, guint64 downloadSize, guint64 installedSize) | 1036 | void FlatpakBackend::onFetchSizeFinished(FlatpakResource *resource, guint64 downloadSize, guint64 installedSize) | ||
1013 | { | 1037 | { | ||
1014 | FlatpakResource *runtime = nullptr; | 1038 | FlatpakResource *runtime = nullptr; | ||
▲ Show 20 Lines • Show All 217 Lines • Show Last 20 Lines |