DownloadWorker: Do cleanup on download failure/cancellation
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -27,16 +27,15 @@ import com.aurora.store.data.receiver.InstallReceiver
|
|||||||
import com.aurora.store.util.NotificationUtil
|
import com.aurora.store.util.NotificationUtil
|
||||||
import com.aurora.store.util.PathUtil
|
import com.aurora.store.util.PathUtil
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import java.io.File
|
|
||||||
import java.net.URL
|
|
||||||
import java.nio.file.Path
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.io.path.Path
|
import java.io.File
|
||||||
import kotlin.io.path.absolutePathString
|
import java.net.URL
|
||||||
|
import kotlin.io.path.ExperimentalPathApi
|
||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteRecursively
|
||||||
import com.aurora.gplayapi.data.models.File as GPlayFile
|
import com.aurora.gplayapi.data.models.File as GPlayFile
|
||||||
|
|
||||||
class DownloadWorker(private val appContext: Context, workerParams: WorkerParameters) :
|
class DownloadWorker(private val appContext: Context, workerParams: WorkerParameters) :
|
||||||
@@ -66,6 +65,7 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var app: App
|
private lateinit var app: App
|
||||||
|
private lateinit var notificationManager: NotificationManager
|
||||||
private var downloading = false
|
private var downloading = false
|
||||||
|
|
||||||
private val TAG = DownloadWorker::class.java.simpleName
|
private val TAG = DownloadWorker::class.java.simpleName
|
||||||
@@ -79,6 +79,9 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
val purchaseHelper = PurchaseHelper(authData)
|
val purchaseHelper = PurchaseHelper(authData)
|
||||||
.using(HttpClient.getPreferredClient(appContext))
|
.using(HttpClient.getPreferredClient(appContext))
|
||||||
|
|
||||||
|
notificationManager =
|
||||||
|
appContext.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
|
||||||
// Try to parse input data into a valid app
|
// Try to parse input data into a valid app
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
try {
|
try {
|
||||||
@@ -107,12 +110,25 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
val requestList = getDownloadRequest(files)
|
val requestList = getDownloadRequest(files)
|
||||||
requestList.forEach { request ->
|
requestList.forEach { request ->
|
||||||
downloading = true
|
downloading = true
|
||||||
downloadFile(request)
|
runCatching { downloadFile(request) }
|
||||||
while (downloading && !isStopped) {
|
.onSuccess { downloading = false }
|
||||||
|
.onFailure {
|
||||||
|
Log.e(TAG, "Failed to download ${app.packageName}", it)
|
||||||
|
downloading = false
|
||||||
|
onFailure()
|
||||||
|
return Result.failure()
|
||||||
|
}
|
||||||
|
while (downloading) {
|
||||||
delay(1000)
|
delay(1000)
|
||||||
|
if (isStopped) {
|
||||||
|
onFailure()
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!requestList.all { File(it.filePath).exists() }) return Result.failure()
|
||||||
|
|
||||||
// Mark download as completed
|
// Mark download as completed
|
||||||
notifyStatus(DownloadStatus.COMPLETED)
|
notifyStatus(DownloadStatus.COMPLETED)
|
||||||
Log.i(TAG, "Finished downloading ${app.packageName}")
|
Log.i(TAG, "Finished downloading ${app.packageName}")
|
||||||
@@ -127,6 +143,14 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
|
private fun onFailure() {
|
||||||
|
Log.i(TAG, "Cleaning up!")
|
||||||
|
PathUtil.getAppDownloadDir(appContext, app.packageName, app.versionCode)
|
||||||
|
.deleteRecursively()
|
||||||
|
notificationManager.cancel(notificationID)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getDownloadRequest(files: List<GPlayFile>): List<Request> {
|
private fun getDownloadRequest(files: List<GPlayFile>): List<Request> {
|
||||||
val downloadList = mutableListOf<Request>()
|
val downloadList = mutableListOf<Request>()
|
||||||
files.filter { it.url.isNotBlank() }.forEach {
|
files.filter { it.url.isNotBlank() }.forEach {
|
||||||
@@ -156,24 +180,23 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
if (!File(request.filePath).exists()) {
|
if (!File(request.filePath).exists()) {
|
||||||
Log.e(TAG, "Failed to find downloaded file at ${request.filePath}")
|
Log.e(TAG, "Failed to find downloaded file at ${request.filePath}")
|
||||||
notifyStatus(DownloadStatus.FAILED)
|
notifyStatus(DownloadStatus.FAILED)
|
||||||
downloading = false
|
|
||||||
return@withContext Result.failure()
|
return@withContext Result.failure()
|
||||||
}
|
}
|
||||||
downloading = false
|
|
||||||
return@withContext Result.success()
|
return@withContext Result.success()
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
Log.e(TAG, "Failed to download ${request.filePath}!", exception)
|
Log.e(TAG, "Failed to download ${request.filePath}!", exception)
|
||||||
requestFile.delete()
|
requestFile.delete()
|
||||||
notifyStatus(DownloadStatus.FAILED)
|
notifyStatus(DownloadStatus.FAILED)
|
||||||
downloading = false
|
|
||||||
return@withContext Result.failure()
|
return@withContext Result.failure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onProgress(progress: Int) {
|
private suspend fun onProgress(progress: Int) {
|
||||||
setProgress(Data.Builder().putInt(DOWNLOAD_PROGRESS, progress).build())
|
if (!isStopped) {
|
||||||
notifyStatus(DownloadStatus.DOWNLOADING, progress, notificationID)
|
setProgress(Data.Builder().putInt(DOWNLOAD_PROGRESS, progress).build())
|
||||||
|
notifyStatus(DownloadStatus.DOWNLOADING, progress, notificationID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getForegroundInfo(): ForegroundInfo {
|
override suspend fun getForegroundInfo(): ForegroundInfo {
|
||||||
@@ -192,8 +215,6 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyStatus(status: DownloadStatus, progress: Int = 100, dID: Int = -1) {
|
private fun notifyStatus(status: DownloadStatus, progress: Int = 100, dID: Int = -1) {
|
||||||
val notificationManager =
|
|
||||||
appContext.getSystemService(Service.NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
val notification =
|
val notification =
|
||||||
NotificationUtil.getDownloadNotification(appContext, app, status, progress, id)
|
NotificationUtil.getDownloadNotification(appContext, app, status, progress, id)
|
||||||
notificationManager.notify(if (dID != -1) dID else app.packageName.hashCode(), notification)
|
notificationManager.notify(if (dID != -1) dID else app.packageName.hashCode(), notification)
|
||||||
|
|||||||
Reference in New Issue
Block a user