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

Commit 6e69b4ae authored by Hasib Prince's avatar Hasib Prince Committed by Sayantan Roychowdhury
Browse files

improved handling of download failure

parent 6372b633
Loading
Loading
Loading
Loading
+5 −26
Original line number Diff line number Diff line
@@ -141,6 +141,10 @@ class DownloadManager @Inject constructor(
        return getDownloadStatus(downloadId) == DownloadManager.STATUS_SUCCESSFUL
    }

    fun hasDownloadFailed(downloadId: Long): Boolean {
        return getDownloadStatus(downloadId) == DownloadManager.STATUS_FAILED
    }

    private fun getDownloadStatus(downloadId: Long): Int {
        try {
            downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
@@ -148,7 +152,7 @@ class DownloadManager @Inject constructor(
                    if (cursor.moveToFirst()) {
                        val status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                        Timber.d("Download Failed: downloadId: $downloadId $status")
                        Timber.d("Download Status: downloadId: $downloadId $status")
                        return status
                    }
                }
@@ -157,29 +161,4 @@ class DownloadManager @Inject constructor(
        }
        return DownloadManager.STATUS_FAILED
    }

    suspend fun checkDownloadProcess(downloadingIds: LongArray, handleFailed: suspend () -> Unit) {
        try {
            downloadManager.query(downloadManagerQuery.setFilterById(*downloadingIds))
                .use { cursor ->

                    if (!cursor.moveToFirst()) {
                        return@use
                    }

                    while (!cursor.isAfterLast) {
                        val status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))

                        if (status == DownloadManager.STATUS_FAILED) {
                            handleFailed()
                        }

                        cursor.moveToNext()
                    }
                }
        } catch (e: Exception) {
            Timber.e(e)
        }
    }
}
+24 −8
Original line number Diff line number Diff line
@@ -64,15 +64,30 @@ class DownloadManagerUtils @Inject constructor(
                        fusedDownload.downloadIdMap.values.filter { it }.size
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")

                    if (downloadManager.hasDownloadFailed(downloadId)) {
                        handleDownloadFailed(fusedDownload)
                        return@launch
                    }

                    if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) {
                        handleDownloadSuccess(fusedDownload)
                    }
                }
            }
        }
    }

    private suspend fun handleDownloadSuccess(fusedDownload: FusedDownload) {
        Timber.i("===> Download is completed for: ${fusedDownload.name}")
        fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload)
        fusedDownload.status = Status.DOWNLOADED
        fusedManagerRepository.updateFusedDownload(fusedDownload)
    }
                }
            }
        }

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

    private suspend fun validateDownload(
@@ -89,6 +104,7 @@ class DownloadManagerUtils @Inject constructor(
        numberOfDownloadedItems: Int,
        fusedDownload: FusedDownload
    ) = numberOfDownloadedItems == fusedDownload.downloadIdMap.size
            && numberOfDownloadedItems == fusedDownload.downloadURLList.size

    private suspend fun updateDownloadIdMap(
        fusedDownload: FusedDownload,
+3 −1
Original line number Diff line number Diff line
@@ -156,8 +156,10 @@ class FusedManagerImpl @Inject constructor(

            // Reset the status before deleting download
            updateDownloadStatus(fusedDownload, fusedDownload.orgStatus)

            if (fusedDownload.status != Status.INSTALLATION_ISSUE) {
                databaseRepository.deleteDownload(fusedDownload)
            }

            flushOldDownload(fusedDownload.packageName)
        } else {
            Timber.d("Unable to cancel download!")
+11 −22
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ class AppInstallProcessor @Inject constructor(
    @ApplicationContext private val context: Context,
    private val databaseRepository: DatabaseRepository,
    private val fusedManagerRepository: FusedManagerRepository,
    private val downloadManager: DownloadManager,
    private val dataStoreManager: DataStoreManager
) {

@@ -86,10 +85,7 @@ class AppInstallProcessor @Inject constructor(
                    return@let
                }

                if (fusedDownload.areFilesDownloaded() && !fusedManagerRepository.isFusedDownloadInstalled(
                        fusedDownload
                    )
                ) {
                if (areFilesDownloadedButNotInstalled(fusedDownload)) {
                    Timber.i("===> Downloaded But not installed ${fusedDownload.name}")
                    fusedManagerRepository.updateDownloadStatus(fusedDownload, Status.INSTALLING)
                }
@@ -108,7 +104,7 @@ class AppInstallProcessor @Inject constructor(
        } catch (e: Exception) {
            Timber.e("doWork: Failed: ${e.stackTraceToString()}")
            fusedDownload?.let {
                fusedManagerRepository.installationIssue(it)
                fusedManagerRepository.cancelDownload(fusedDownload)
            }
        }

@@ -116,6 +112,11 @@ class AppInstallProcessor @Inject constructor(
        return Result.success(ResultStatus.OK)
    }

    private fun areFilesDownloadedButNotInstalled(fusedDownload: FusedDownload) =
        fusedDownload.areFilesDownloaded() && (!fusedManagerRepository.isFusedDownloadInstalled(
            fusedDownload
        ) || fusedDownload.status == Status.INSTALLING)

    private suspend fun checkUpdateWork(
        fusedDownload: FusedDownload?
    ) {
@@ -182,29 +183,23 @@ class AppInstallProcessor @Inject constructor(
            .onEach {
                val download = databaseRepository.getDownloadById(fusedDownload.id)
                if (download == null) {
                    Timber.d("===> download null: finish installation")
                    finishInstallation(fusedDownload)
                } else {
                    handleFusedDownloadStatusCheckingException(download)
                    if (isAppDownloading(download)) {
                        checkDownloadProcess(download)
                    }
                }
            }.launchIn(CoroutineScope(Dispatchers.IO))
        Timber.d(">>> ===> doWork: Download started " + fusedDownload.name + " " + fusedDownload.status)
        return true
    }

    private fun isAppDownloading(download: FusedDownload): Boolean {
        return download.type == Type.NATIVE && download.status != Status.INSTALLED && download.status != Status.INSTALLATION_ISSUE
    }

    private suspend fun handleFusedDownloadStatusCheckingException(
        download: FusedDownload
    ) {
        try {
            handleFusedDownloadStatus(download)
        } catch (e: Exception) {
            Log.e(TAG, "observeDownload: ", e)
            Timber.tag(TAG).e(e, "observeDownload: ")
            finishInstallation(download)
        }
    }
@@ -222,12 +217,6 @@ class AppInstallProcessor @Inject constructor(
        }
    }

    private suspend fun checkDownloadProcess(fusedDownload: FusedDownload) {
        downloadManager.checkDownloadProcess(fusedDownload.downloadIdMap.keys.toLongArray()) {
            fusedManagerRepository.installationIssue(fusedDownload)
        }
    }

    private suspend fun handleFusedDownloadStatus(fusedDownload: FusedDownload) {
        when (fusedDownload.status) {
            Status.AWAITING, Status.DOWNLOADING -> {
@@ -239,15 +228,15 @@ class AppInstallProcessor @Inject constructor(
                Timber.i("===> doWork: Installing ${fusedDownload.name} ${fusedDownload.status}")
            }
            Status.INSTALLED, Status.INSTALLATION_ISSUE -> {
                finishInstallation(fusedDownload)
                Timber.i("===> doWork: Installed/Failed: ${fusedDownload.name} ${fusedDownload.status}")
                finishInstallation(fusedDownload)
            }
            else -> {
                finishInstallation(fusedDownload)
                Timber.wtf(
                    TAG,
                    "===> ${fusedDownload.name} is in wrong state ${fusedDownload.status}"
                )
                finishInstallation(fusedDownload)
            }
        }
    }