Loading app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +2 −2 Original line number Diff line number Diff line Loading @@ -185,8 +185,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { downloadPB.visibility = View.VISIBLE appSize.visibility = View.GONE applicationViewModel.downloadProgress.observe(viewLifecycleOwner) { downloadPB.max = it.totalSizeBytes.toInt() downloadPB.progress = it.bytesDownloadedSoFar.toInt() downloadPB.max = it.totalSizeBytes.values.sum().toInt() downloadPB.progress = it.bytesDownloadedSoFar.values.sum().toInt() } } Status.INSTALLING, Status.UNINSTALLING -> { Loading app/src/main/java/foundation/e/apps/manager/download/data/DownloadProgress.kt +3 −2 Original line number Diff line number Diff line package foundation.e.apps.manager.download.data data class DownloadProgress( val totalSizeBytes: Long = 0, val bytesDownloadedSoFar: Long = 0 var totalSizeBytes: MutableMap<Long, Long> = mutableMapOf(), var bytesDownloadedSoFar: MutableMap<Long, Long> = mutableMapOf(), var status: MutableMap<Long, Boolean> = mutableMapOf() ) app/src/main/java/foundation/e/apps/manager/download/data/DownloadProgressLD.kt +52 −14 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ import androidx.lifecycle.LiveData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -16,6 +18,7 @@ class DownloadProgressLD @Inject constructor( ) : LiveData<DownloadProgress>(), CoroutineScope { private val job = Job() private var downloadProgress = DownloadProgress() override val coroutineContext: CoroutineContext get() = Dispatchers.IO + job Loading @@ -23,24 +26,43 @@ class DownloadProgressLD @Inject constructor( override fun onActive() { super.onActive() launch { while (isActive) { val cursor = downloadManager.query(downloadManagerQuery) while (cursor.moveToNext()) { when (cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))) { DownloadManager.STATUS_SUCCESSFUL, DownloadManager.STATUS_PENDING, DownloadManager.STATUS_FAILED, DownloadManager.STATUS_PAUSED -> { } else -> { val downloadProgress = DownloadProgress( cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)), while (isActive && downloadId.isNotEmpty()) { downloadManager.query(downloadManagerQuery.setFilterById(*downloadId.toLongArray())) .use { cursor -> if (cursor.moveToFirst()) { val id = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID)) val status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) val totalSizeBytes = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)) val bytesDownloadedSoFar = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)) ) if (!downloadProgress.totalSizeBytes.containsKey(id) || downloadProgress.totalSizeBytes[id] != totalSizeBytes ) { downloadProgress.totalSizeBytes[id] = totalSizeBytes } if (!downloadProgress.bytesDownloadedSoFar.containsKey(id) || downloadProgress.bytesDownloadedSoFar[id] != bytesDownloadedSoFar ) { downloadProgress.bytesDownloadedSoFar[id] = bytesDownloadedSoFar } downloadProgress.status[id] = status == DownloadManager.STATUS_SUCCESSFUL postValue(downloadProgress) if (downloadProgress.status.all { it.value }) { clearDownload() cancel() } } } delay(500) } } } Loading @@ -49,4 +71,20 @@ class DownloadProgressLD @Inject constructor( super.onInactive() job.cancel() } companion object { private var downloadId = mutableListOf<Long>() fun setDownloadId(id: Long) { if (id == -1L) { clearDownload() return } downloadId.add(id) } private fun clearDownload() { downloadId.clear() } } } app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt +9 −5 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import androidx.annotation.RequiresApi import androidx.lifecycle.LiveData import foundation.e.apps.manager.database.DatabaseRepository import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.download.data.DownloadProgressLD import foundation.e.apps.manager.pkg.PkgManagerModule import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.enums.Type Loading Loading @@ -128,19 +129,22 @@ class FusedManagerImpl @Inject constructor( private suspend fun downloadNativeApp(fusedDownload: FusedDownload) { var count = 0 fusedDownload.downloadURLList.forEach { count += 1 val parentPath = "$cacheDir/${fusedDownload.package_name}" val packagePath = File(parentPath, "${fusedDownload.package_name}_$count.apk") // Clean old downloads and re-create download dir flushOldDownload(fusedDownload.package_name) File(parentPath).mkdir() DownloadProgressLD.setDownloadId(-1L) fusedDownload.downloadURLList.forEach { count += 1 val packagePath = File(parentPath, "${fusedDownload.package_name}_$count.apk") val request = DownloadManager.Request(Uri.parse(it)) .setTitle(if (count == 1) fusedDownload.name else "Additional file for ${fusedDownload.name}") .setDestinationUri(Uri.fromFile(packagePath)) val requestId = downloadManager.enqueue(request) DownloadProgressLD.setDownloadId(requestId) fusedDownload.apply { status = Status.DOWNLOADING downloadIdMap[requestId] = false Loading Loading
app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt +2 −2 Original line number Diff line number Diff line Loading @@ -185,8 +185,8 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) { downloadPB.visibility = View.VISIBLE appSize.visibility = View.GONE applicationViewModel.downloadProgress.observe(viewLifecycleOwner) { downloadPB.max = it.totalSizeBytes.toInt() downloadPB.progress = it.bytesDownloadedSoFar.toInt() downloadPB.max = it.totalSizeBytes.values.sum().toInt() downloadPB.progress = it.bytesDownloadedSoFar.values.sum().toInt() } } Status.INSTALLING, Status.UNINSTALLING -> { Loading
app/src/main/java/foundation/e/apps/manager/download/data/DownloadProgress.kt +3 −2 Original line number Diff line number Diff line package foundation.e.apps.manager.download.data data class DownloadProgress( val totalSizeBytes: Long = 0, val bytesDownloadedSoFar: Long = 0 var totalSizeBytes: MutableMap<Long, Long> = mutableMapOf(), var bytesDownloadedSoFar: MutableMap<Long, Long> = mutableMapOf(), var status: MutableMap<Long, Boolean> = mutableMapOf() )
app/src/main/java/foundation/e/apps/manager/download/data/DownloadProgressLD.kt +52 −14 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ import androidx.lifecycle.LiveData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -16,6 +18,7 @@ class DownloadProgressLD @Inject constructor( ) : LiveData<DownloadProgress>(), CoroutineScope { private val job = Job() private var downloadProgress = DownloadProgress() override val coroutineContext: CoroutineContext get() = Dispatchers.IO + job Loading @@ -23,24 +26,43 @@ class DownloadProgressLD @Inject constructor( override fun onActive() { super.onActive() launch { while (isActive) { val cursor = downloadManager.query(downloadManagerQuery) while (cursor.moveToNext()) { when (cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))) { DownloadManager.STATUS_SUCCESSFUL, DownloadManager.STATUS_PENDING, DownloadManager.STATUS_FAILED, DownloadManager.STATUS_PAUSED -> { } else -> { val downloadProgress = DownloadProgress( cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)), while (isActive && downloadId.isNotEmpty()) { downloadManager.query(downloadManagerQuery.setFilterById(*downloadId.toLongArray())) .use { cursor -> if (cursor.moveToFirst()) { val id = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID)) val status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) val totalSizeBytes = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)) val bytesDownloadedSoFar = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)) ) if (!downloadProgress.totalSizeBytes.containsKey(id) || downloadProgress.totalSizeBytes[id] != totalSizeBytes ) { downloadProgress.totalSizeBytes[id] = totalSizeBytes } if (!downloadProgress.bytesDownloadedSoFar.containsKey(id) || downloadProgress.bytesDownloadedSoFar[id] != bytesDownloadedSoFar ) { downloadProgress.bytesDownloadedSoFar[id] = bytesDownloadedSoFar } downloadProgress.status[id] = status == DownloadManager.STATUS_SUCCESSFUL postValue(downloadProgress) if (downloadProgress.status.all { it.value }) { clearDownload() cancel() } } } delay(500) } } } Loading @@ -49,4 +71,20 @@ class DownloadProgressLD @Inject constructor( super.onInactive() job.cancel() } companion object { private var downloadId = mutableListOf<Long>() fun setDownloadId(id: Long) { if (id == -1L) { clearDownload() return } downloadId.add(id) } private fun clearDownload() { downloadId.clear() } } }
app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt +9 −5 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import androidx.annotation.RequiresApi import androidx.lifecycle.LiveData import foundation.e.apps.manager.database.DatabaseRepository import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.download.data.DownloadProgressLD import foundation.e.apps.manager.pkg.PkgManagerModule import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.enums.Type Loading Loading @@ -128,19 +129,22 @@ class FusedManagerImpl @Inject constructor( private suspend fun downloadNativeApp(fusedDownload: FusedDownload) { var count = 0 fusedDownload.downloadURLList.forEach { count += 1 val parentPath = "$cacheDir/${fusedDownload.package_name}" val packagePath = File(parentPath, "${fusedDownload.package_name}_$count.apk") // Clean old downloads and re-create download dir flushOldDownload(fusedDownload.package_name) File(parentPath).mkdir() DownloadProgressLD.setDownloadId(-1L) fusedDownload.downloadURLList.forEach { count += 1 val packagePath = File(parentPath, "${fusedDownload.package_name}_$count.apk") val request = DownloadManager.Request(Uri.parse(it)) .setTitle(if (count == 1) fusedDownload.name else "Additional file for ${fusedDownload.name}") .setDestinationUri(Uri.fromFile(packagePath)) val requestId = downloadManager.enqueue(request) DownloadProgressLD.setDownloadId(requestId) fusedDownload.apply { status = Status.DOWNLOADING downloadIdMap[requestId] = false Loading