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

Commit 93a5549b authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

Merge branch '7102-Show_notification_on_no_space_to_download' into 'main'

7102-Show_notification_on_no_space_to_download

See merge request !375
parents 70f79e1a 181f7798
Loading
Loading
Loading
Loading
Loading
+61 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package foundation.e.apps.data

import android.app.DownloadManager
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Environment
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -35,6 +36,7 @@ import java.io.File
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
import kotlin.math.abs
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

@@ -124,12 +126,17 @@ class DownloadManager @Inject constructor(
            downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
                .use { cursor ->
                    if (cursor.moveToFirst()) {
                        val status =
                        var status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                        val totalSizeBytes =
                            cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
                            getLong(cursor, DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
                        val bytesDownloadedSoFar =
                            cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
                            getLong(cursor, DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
                        val reason =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON))

                        status = sanitizeStatus(downloadId, status, reason)

                        if (status == DownloadManager.STATUS_FAILED) {
                            Timber.d("Download Failed: $filePath=> $bytesDownloadedSoFar/$totalSizeBytes $status")
                            downloadsMaps[downloadId] = false
@@ -166,6 +173,34 @@ class DownloadManager @Inject constructor(
        return getDownloadStatus(downloadId) == DownloadManager.STATUS_FAILED
    }

    fun getSizeRequired(downloadId: Long): Long {
        var totalSizeBytes = -1L
        var bytesDownloadedSoFar = -1L

        try {
            downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
                .use { cursor ->
                    if (cursor.moveToFirst()) {
                        totalSizeBytes = getLong(cursor, DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
                        bytesDownloadedSoFar =
                            getLong(cursor, DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
                    }
                }
        } catch (e: RuntimeException) {
            Timber.e(e, "runtime exception on retrieving download file size.")
        }

        if (totalSizeBytes <= 0) {
            return 0
        }

        if (bytesDownloadedSoFar <= 0) {
            return totalSizeBytes
        }

        return abs(totalSizeBytes - bytesDownloadedSoFar)
    }

    private fun getDownloadStatus(downloadId: Long): Int {
        var status = -1
        var reason = -1
@@ -187,9 +222,28 @@ class DownloadManager @Inject constructor(
        if (status != DownloadManager.STATUS_SUCCESSFUL) {
            Timber.e("Download Issue: $downloadId status: $status reason: $reason")
        }

        return sanitizeStatus(downloadId, status, reason)
    }

    private fun sanitizeStatus(downloadId: Long, status: Int, reason: Int): Int {
        if (reason <= 0) {
            return status
        }

        if (status in listOf(DownloadManager.STATUS_FAILED, DownloadManager.STATUS_PAUSED)) {
            return status
        }

        Timber.e("Download Issue: $downloadId : DownloadManager returns status: $status but the failed because: reason: $reason")

        if (reason <= DownloadManager.PAUSED_UNKNOWN) {
            return DownloadManager.STATUS_PAUSED
        }

        return DownloadManager.STATUS_FAILED
    }

    fun getDownloadFailureReason(downloadId: Long): Int {
        var reason = -1
        try {
@@ -205,4 +259,7 @@ class DownloadManager @Inject constructor(
        }
        return reason
    }

    private fun getLong(cursor: Cursor, column: String) =
        cursor.getLong(cursor.getColumnIndexOrThrow(column))
}
+0 −3
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import com.aurora.gplayapi.data.models.SearchBundle
import com.aurora.gplayapi.data.models.StreamCluster
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.Constants.timeoutDurationInMillis
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.cleanapk.CleanApkDownloadInfoFetcher
import foundation.e.apps.data.cleanapk.CleanApkRetrofit
@@ -68,10 +67,8 @@ import foundation.e.apps.install.pkg.PWAManagerModule
import foundation.e.apps.install.pkg.PkgManagerModule
import foundation.e.apps.ui.home.model.HomeChildFusedAppDiffUtil
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withTimeout
import retrofit2.Response
import timber.log.Timber
import javax.inject.Inject
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ data class FusedDownload(
    val versionCode: Int = 1,
    val offerType: Int = -1,
    val isFree: Boolean = true,
    val appSize: Long = 0,
    var appSize: Long = 0,
    var files: List<File> = mutableListOf(),
    var signature: String = String()
) {
+3 −3
Original line number Diff line number Diff line
@@ -36,12 +36,12 @@ import foundation.e.apps.data.fused.data.FusedApp
import foundation.e.apps.data.preference.PreferenceManagerModule
import foundation.e.apps.install.pkg.PkgManagerModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject

class UpdatesManagerImpl @Inject constructor(
    @ApplicationContext private val context: Context,
+20 −14
Original line number Diff line number Diff line
@@ -20,11 +20,15 @@ package foundation.e.apps.install.download

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.DownloadManager
import foundation.e.apps.data.enums.Origin
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.fusedDownload.FusedManagerRepository
import foundation.e.apps.data.fusedDownload.models.FusedDownload
import foundation.e.apps.install.notification.StorageNotificationManager
import foundation.e.apps.utils.eventBus.AppEvent
import foundation.e.apps.utils.eventBus.EventBus
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@@ -39,7 +43,8 @@ import javax.inject.Singleton
class DownloadManagerUtils @Inject constructor(
    @ApplicationContext private val context: Context,
    private val fusedManagerRepository: FusedManagerRepository,
    private val downloadManager: DownloadManager
    private val downloadManager: DownloadManager,
    private val storageNotificationManager: StorageNotificationManager,
) {
    private val mutex = Mutex()

@@ -64,10 +69,9 @@ class DownloadManagerUtils @Inject constructor(
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")

                    if (downloadManager.hasDownloadFailed(downloadId)) {
                        handleDownloadFailed(fusedDownload)
                        handleDownloadFailed(fusedDownload, downloadId)
                        Timber.e(
                            "Download failed for ${fusedDownload.packageName}, " +
                                "reason: ${downloadManager.getDownloadFailureReason(downloadId)}"
                            "Download failed for ${fusedDownload.packageName}, " + "reason: " + "${downloadManager.getDownloadFailureReason(downloadId)}"
                        )
                        return@launch
                    }
@@ -87,27 +91,30 @@ class DownloadManagerUtils @Inject constructor(
        fusedManagerRepository.updateFusedDownload(fusedDownload)
    }

    private suspend fun handleDownloadFailed(fusedDownload: FusedDownload) {
    private suspend fun handleDownloadFailed(fusedDownload: FusedDownload, downloadId: Long) {
        fusedManagerRepository.installationIssue(fusedDownload)
        fusedManagerRepository.cancelDownload(fusedDownload)
        Timber.w("===> Download failed: ${fusedDownload.name} ${fusedDownload.status}")

        if (downloadManager.getDownloadFailureReason(downloadId) == android.app.DownloadManager.ERROR_INSUFFICIENT_SPACE) {
            storageNotificationManager.showNotEnoughSpaceNotification(fusedDownload, downloadId)
            EventBus.invokeEvent(AppEvent.ErrorMessageEvent(R.string.not_enough_storage))
        }
    }

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

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

    private suspend fun updateDownloadIdMap(
        fusedDownload: FusedDownload,
@@ -119,8 +126,7 @@ class DownloadManagerUtils @Inject constructor(

    private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean {
        if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned(
                context,
                fusedDownload
                context, fusedDownload
            )
        ) {
            Timber.d("Apk signature is OK")
Loading