fix(installer): progress tracking

This commit is contained in:
Ax333l 2023-07-31 12:14:51 +02:00
parent 6beb34baa8
commit 272d911464
3 changed files with 23 additions and 50 deletions

View File

@ -1,8 +1,5 @@
package app.revanced.manager.patcher
import android.util.Log
import app.revanced.manager.patcher.worker.Progress
import app.revanced.manager.util.tag
import app.revanced.patcher.Patcher
import app.revanced.patcher.PatcherOptions
import app.revanced.patcher.data.Context
@ -24,7 +21,7 @@ class Session(
aaptPath: String,
private val logger: Logger,
private val input: File,
private val onProgress: suspend (Progress) -> Unit = { }
private val onStepSucceeded: suspend () -> Unit
) : Closeable {
private val temporary = File(cacheDir).resolve("manager").also { it.mkdirs() }
private val patcher = Patcher(
@ -41,7 +38,7 @@ class Session(
this.executePatches(true).forEach { (patch, result) ->
if (result.isSuccess) {
logger.info("$patch succeeded")
onProgress(Progress.PatchSuccess(patch))
onStepSucceeded()
return@forEach
}
logger.error("$patch failed:")
@ -54,20 +51,17 @@ class Session(
}
suspend fun run(output: File, selectedPatches: PatchList, integrations: List<File>) {
onProgress(Progress.Merging)
onStepSucceeded() // Unpacking
with(patcher) {
logger.info("Merging integrations")
addIntegrations(integrations) {}
addPatches(selectedPatches)
onStepSucceeded() // Merging
logger.info("Applying patches...")
onProgress(Progress.PatchingStart)
applyPatchesVerbose()
}
onProgress(Progress.Saving)
logger.info("Writing patched files...")
val result = patcher.save()
@ -78,6 +72,7 @@ class Session(
withContext(Dispatchers.IO) {
Files.move(aligned.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
onStepSucceeded() // Saving
}
override fun close() {

View File

@ -9,17 +9,6 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.StateFlow
sealed class Progress {
object Downloading : Progress()
object Unpacking : Progress()
object Merging : Progress()
object PatchingStart : Progress()
data class PatchSuccess(val patchName: String) : Progress()
object Saving : Progress()
}
enum class State {
WAITING, COMPLETED, FAILED
}
@ -76,20 +65,13 @@ class PatcherProgressManager(context: Context, selectedPatches: List<String>, se
}
fun replacePatchesList(newList: List<String>) {
steps[stepKeyMap[Progress.PatchingStart]!!.step] = generatePatchesStep(newList)
steps[1] = generatePatchesStep(newList)
}
private fun updateCurrent(newState: State, message: String? = null) {
currentStep?.let { update(it, newState, message) }
}
fun handle(progress: Progress) = when (val step = stepKeyMap[progress]) {
null -> success()
currentStep -> {}
else -> success().also { currentStep = step }
}
fun failure(error: Throwable) = updateCurrent(
State.FAILED,
error.stackTraceToString()
@ -100,17 +82,6 @@ class PatcherProgressManager(context: Context, selectedPatches: List<String>, se
fun getProgress(): List<Step> = steps
companion object {
/**
* A map of [Progress] to the corresponding position in [steps]
*/
private val stepKeyMap = mapOf(
//Progress.Downloading to StepKey(0, 1),
//Progress.Unpacking to StepKey(0, 2),
//Progress.Merging to StepKey(0, 3),
Progress.PatchingStart to StepKey(1, 0),
//Progress.Saving to StepKey(2, 0),
)
private fun generatePatchesStep(selectedPatches: List<String>) = Step(
R.string.patcher_step_group_patching,
selectedPatches.map { SubStep(it) }.toImmutableList()

View File

@ -130,12 +130,19 @@ class PatcherWorker(
val downloadProgress = MutableStateFlow<Pair<Float, Float>?>(null)
val progressManager =
PatcherProgressManager(applicationContext, args.selectedPatches.flatMap { it.value }, args.input, downloadProgress)
PatcherProgressManager(
applicationContext,
args.selectedPatches.flatMap { it.value },
args.input,
downloadProgress
)
val progressFlow = args.progress
fun updateProgress(progress: Progress?) {
progress?.let { progressManager.handle(it) }
fun updateProgress(advanceCounter: Boolean = true) {
if (advanceCounter) {
progressManager.success()
}
progressFlow.value = progressManager.getProgress().toImmutableList()
}
@ -165,12 +172,12 @@ class PatcherWorker(
// Ensure they are in the correct order so we can track progress properly.
progressManager.replacePatchesList(patches.map { it.patchName })
updateProgress() // Loading patches
val inputFile = when (val selectedApp = args.input) {
is SelectedApp.Download -> {
updateProgress(Progress.Downloading)
val savePath = applicationContext.filesDir.resolve("downloaded-apps").resolve(args.input.packageName).also { it.mkdirs() }
val savePath = applicationContext.filesDir.resolve("downloaded-apps")
.resolve(args.input.packageName).also { it.mkdirs() }
selectedApp.app.download(
savePath,
@ -182,21 +189,21 @@ class PatcherWorker(
args.input.version,
it
)
updateProgress() // Downloading
}
}
is SelectedApp.Local -> selectedApp.file
is SelectedApp.Installed -> File(pm.getPackageInfo(selectedApp.packageName)!!.applicationInfo.sourceDir)
}
updateProgress(Progress.Unpacking)
Session(
applicationContext.cacheDir.absolutePath,
frameworkPath,
aaptPath,
args.logger,
inputFile,
onProgress = { updateProgress(it) }
onStepSucceeded = ::updateProgress
).use { session ->
session.run(File(args.output), patches, integrations)
}
@ -209,7 +216,7 @@ class PatcherWorker(
progressManager.failure(e)
Result.failure()
} finally {
updateProgress(null)
updateProgress(false)
}
}
}