Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e460951 authored by Hasib Prince's avatar Hasib Prince
Browse files

Merge branch '5922-update_all' into 'main'

improved behavior of update process

See merge request !197
parents f51b3cde f9785310
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -478,6 +478,7 @@ class MainActivityViewModel @Inject constructor(
        if (shouldShowPaidAppsSnackBar(app)) {
            return
        }

        viewModelScope.launch {
            val fusedDownload: FusedDownload
            try {
+26 −1
Original line number Diff line number Diff line
@@ -127,11 +127,36 @@ class DownloadManager @Inject constructor(
        }
    }

    private fun tickerFlow(downloadId: Long, period: Duration, initialDelay: Duration = Duration.ZERO) = flow {
    private fun tickerFlow(
        downloadId: Long,
        period: Duration,
        initialDelay: Duration = Duration.ZERO
    ) = flow {
        delay(initialDelay)
        while (downloadsMaps[downloadId]!!) {
            emit(Unit)
            delay(period)
        }
    }

    fun isDownloadSuccessful(downloadId: Long): Boolean {
        return getDownloadStatus(downloadId) == DownloadManager.STATUS_SUCCESSFUL
    }

    private fun getDownloadStatus(downloadId: Long): Int {
        try {
            downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
                .use { cursor ->
                    if (cursor.moveToFirst()) {
                        val status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                        Timber.d("Download Failed: downloadId: $downloadId $status")
                        return status
                    }
                }
        } catch (e: Exception) {
            Timber.e(e)
        }
        return DownloadManager.STATUS_FAILED
    }
}
+11 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import org.bouncycastle.openpgp.PGPUtil
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator
import timber.log.Timber
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.io.InputStream
@@ -35,11 +36,16 @@ import java.security.Security
object ApkSignatureManager {
    fun verifyFdroidSignature(context: Context, apkFilePath: String, signature: String): Boolean {
        Security.addProvider(BouncyCastleProvider())
        try {
            return verifyAPKSignature(
                BufferedInputStream(FileInputStream(apkFilePath)),
                signature.byteInputStream(Charsets.UTF_8),
                context.assets.open("f-droid.org-signing-key.gpg")
            )
        } catch (e: Exception) {
            Timber.e(e)
        }
        return false
    }

    private fun verifyAPKSignature(
+26 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 2022 MURENA SAS
 *
 *   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 3 of the License, or
 *   (at your option) any later version.
 *
 *   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 <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps.api.fused

import foundation.e.apps.api.fused.data.FusedApp

object UpdatesDao {
    var appsAwaitingForUpdate: List<FusedApp> = listOf()

    fun hasAnyAppsForUpdate() = appsAwaitingForUpdate.isNotEmpty()
}
+115 −88
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package foundation.e.apps.manager.download

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.api.DownloadManager
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.fused.FusedManagerRepository
import foundation.e.apps.utils.enums.Origin
@@ -36,8 +37,9 @@ import javax.inject.Singleton

@Singleton
class DownloadManagerUtils @Inject constructor(
    @ApplicationContext private val context: Context,
    private val fusedManagerRepository: FusedManagerRepository,
    @ApplicationContext private val context: Context
    private val downloadManager: DownloadManager
) {
    private val TAG = DownloadManagerUtils::class.java.simpleName
    private val mutex = Mutex()
@@ -57,11 +59,13 @@ class DownloadManagerUtils @Inject constructor(
                delay(1500) // Waiting for downloadmanager to publish the progress of last bytes
                val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId)
                if (fusedDownload.id.isNotEmpty()) {
                    fusedDownload.downloadIdMap[downloadId] = true
                    fusedManagerRepository.updateFusedDownload(fusedDownload)
                    val downloaded = fusedDownload.downloadIdMap.values.filter { it }.size
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $downloaded/${fusedDownload.downloadIdMap.size}")
                    if (downloaded == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK(fusedDownload)) {
                    updateDownloadIdMap(fusedDownload, downloadId)
                    val numberOfDownloadedItems =
                        fusedDownload.downloadIdMap.values.filter { it }.size
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")

                    if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) {
                        Timber.d("===> Download is completed for: ${fusedDownload.name}")
                        fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload)
                        fusedDownload.status = Status.DOWNLOADED
                        fusedManagerRepository.updateFusedDownload(fusedDownload)
@@ -71,6 +75,29 @@ class DownloadManagerUtils @Inject constructor(
        }
    }

    private suspend fun validateDownload(
        numberOfDownloadedItems: Int,
        fusedDownload: FusedDownload,
        downloadId: Long
    ) = downloadManager.isDownloadSuccessful(downloadId) &&
        areAllFilesDownloaded(
            numberOfDownloadedItems,
            fusedDownload
        ) && checkCleanApkSignatureOK(fusedDownload)

    private fun areAllFilesDownloaded(
        numberOfDownloadedItems: Int,
        fusedDownload: FusedDownload
    ) = numberOfDownloadedItems == fusedDownload.downloadIdMap.size

    private suspend fun updateDownloadIdMap(
        fusedDownload: FusedDownload,
        downloadId: Long
    ) {
        fusedDownload.downloadIdMap[downloadId] = true
        fusedManagerRepository.updateFusedDownload(fusedDownload)
    }

    private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean {
        if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned(
                context,
Loading