Skip to content
This repository has been archived by the owner on Jul 7, 2024. It is now read-only.

Commit

Permalink
Implement the new installer
Browse files Browse the repository at this point in the history
  • Loading branch information
wingio committed Jan 26, 2024
1 parent 9e0994d commit 46a7d04
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 538 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ abstract class Step: KoinComponent {
@get:StringRes
abstract val nameRes: Int

protected abstract suspend fun run(runner: StepRunner)

var status by mutableStateOf(StepStatus.QUEUED)
protected set

Expand All @@ -34,13 +32,15 @@ abstract class Step: KoinComponent {
var durationMs by mutableIntStateOf(0)
private set

protected abstract suspend fun run(runner: StepRunner)

suspend fun runCatching(runner: StepRunner): Throwable? {
if (status != StepStatus.QUEUED)
throw IllegalStateException("Cannot execute a step that has already started")

status = StepStatus.ONGOING

val (error, timeMs) = measureTimedValue {
val (error, time) = measureTimedValue {
try {
run(runner)
status = StepStatus.SUCCESSFUL
Expand All @@ -51,7 +51,7 @@ abstract class Step: KoinComponent {
}
}

durationMs = timeMs.inWholeMilliseconds.toInt()
durationMs = time.inWholeMilliseconds.toInt()
return error
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import android.content.Context
import android.os.Build
import android.os.Environment
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import dev.beefers.vendetta.manager.BuildConfig
import dev.beefers.vendetta.manager.domain.manager.PreferenceManager
import dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep
Expand Down Expand Up @@ -38,14 +41,14 @@ class StepRunner(

private val preferenceManager: PreferenceManager by inject()
private val context: Context by inject()
private var debugInfo = """
private val debugInfo = """
Vendetta Manager v${BuildConfig.VERSION_NAME}
Built from commit ${BuildConfig.GIT_COMMIT} on ${BuildConfig.GIT_BRANCH} ${if (BuildConfig.GIT_LOCAL_CHANGES || BuildConfig.GIT_LOCAL_COMMITS) "(Changes Present)" else ""}
Running Android ${Build.VERSION.RELEASE}, API level ${Build.VERSION.SDK_INT}
Supported ABIs: ${Build.SUPPORTED_ABIS.joinToString()}
Device: ${Build.MANUFACTURER} - ${Build.MODEL} (${Build.DEVICE})
${if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S) "SOC: ${Build.SOC_MANUFACTURER} - ${Build.SOC_MODEL}\n" else "\n\n"}
${if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S) "SOC: ${Build.SOC_MANUFACTURER} ${Build.SOC_MODEL}\n" else "\n\n"}
Adding Vendetta to Discord v$discordVersion
Expand All @@ -66,18 +69,24 @@ class StepRunner(
private val signedDir = discordCacheDir.resolve("signed").also { it.deleteRecursively() }
private val lspatchedDir = patchedDir.resolve("lspatched").also { it.deleteRecursively() }

var currentStep by mutableStateOf<Step?>(null)
private set

var completed by mutableStateOf<Boolean>(false)
private set

/**
* List of steps to go through for this install
*
* ORDER MATTERS
*/
val steps: ImmutableList<Step> = buildList {
// Downloading
add(DownloadBaseStep(discordCacheDir, discordVersion.toVersionCode()))
add(DownloadLibsStep(discordCacheDir, discordVersion.toVersionCode()))
add(DownloadLangStep(discordCacheDir, discordVersion.toVersionCode()))
add(DownloadResourcesStep(discordCacheDir, discordVersion.toVersionCode()))
add(DownloadVendettaStep())
add(DownloadBaseStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))
add(DownloadLibsStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))
add(DownloadLangStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))
add(DownloadResourcesStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))
add(DownloadVendettaStep(patchedDir))

// Patching
if (preferenceManager.patchIcon) add(ReplaceIconStep())
Expand Down Expand Up @@ -106,13 +115,22 @@ class StepRunner(
return step
}

fun clearCache() {
cacheDir.deleteRecursively()
}

suspend fun runAll(): Throwable? {
for (step in steps) {
if (completed) return null // Failsafe in case runner is incorrectly marked as not completed too early

currentStep = step
val error = step.runCatching(this)
if (error != null) {
logger.i("\n")
logger.e("Failed on step ${step::class.simpleName}")
logger.e("Failed on ${step::class.simpleName}")
logger.e(error.stackTraceToString())

completed = true
return error
}

Expand All @@ -123,6 +141,7 @@ class StepRunner(
}
}

completed = true
return null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import java.io.File
@Stable
class DownloadBaseStep(
dir: File,
workingDir: File,
version: String
): DownloadStep() {

override val nameRes = R.string.step_dl_base

override val destination = dir.resolve("base-$version.apk")

override val url: String = "$baseUrl/tracker/download/$version/base"
override val destination = dir.resolve("base-$version.apk")
override val workingCopy = workingDir.resolve("base-$version.apk")

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import java.io.File
@Stable
class DownloadLangStep(
dir: File,
workingDir: File,
version: String
): DownloadStep() {

override val nameRes = R.string.step_dl_lang

override val destination = dir.resolve("config.en-$version.apk")

override val url: String = "$baseUrl/tracker/download/$version/config.en"
override val destination = dir.resolve("config.en-$version.apk")
override val workingCopy = workingDir.resolve("config.en-$version.apk")

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import java.io.File
@Stable
class DownloadLibsStep(
dir: File,
workingDir: File,
version: String
): DownloadStep() {

private val arch = Build.SUPPORTED_ABIS.first().replace("-v", "_v")

override val nameRes = R.string.step_dl_lib

override val destination = dir.resolve("config.$arch-$version.apk")

override val url: String = "$baseUrl/tracker/download/$version/config.$arch"
override val destination = dir.resolve("config.$arch-$version.apk")
override val workingCopy = workingDir.resolve("config.$arch-$version.apk")

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import java.io.File
@Stable
class DownloadResourcesStep(
dir: File,
workingDir: File,
version: String
): DownloadStep() {

override val nameRes = R.string.step_dl_res

override val destination = dir.resolve("config.xxhdpi-$version.apk")

override val url: String = "$baseUrl/tracker/download/$version/config.xxhdpi"
override val destination = dir.resolve("config.xxhdpi-$version.apk")
override val workingCopy = workingDir.resolve("config.xxhdpi-$version.apk")

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep
import java.io.File

@Stable
class DownloadVendettaStep: DownloadStep() {
class DownloadVendettaStep(
workingDir: File
): DownloadStep() {

override val nameRes = R.string.step_dl_vd

override val destination = preferenceManager.moduleLocation

override val url: String = "https://github.com/vendetta-mod/VendettaXposed/releases/latest/download/app-release.apk"
override val destination = preferenceManager.moduleLocation
override val workingCopy = workingDir.resolve("vendetta.apk")

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package dev.beefers.vendetta.manager.installer.step.download.base

import android.content.Context
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import dev.beefers.vendetta.manager.R
import dev.beefers.vendetta.manager.domain.manager.DownloadManager
import dev.beefers.vendetta.manager.domain.manager.DownloadResult
Expand All @@ -16,20 +19,25 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.koin.core.component.inject
import java.io.File
import kotlin.math.roundToInt

@Stable
abstract class DownloadStep: Step() {

val preferenceManager: PreferenceManager by inject()
val baseUrl = preferenceManager.mirror.baseUrl

private val downloadManager: DownloadManager by inject()
private val context: Context by inject()

abstract val url: String
abstract val destination: File
abstract val workingCopy: File

override val group: StepGroup = StepGroup.DL

val preferenceManager: PreferenceManager by inject()
val baseUrl = preferenceManager.mirror.baseUrl
var cached by mutableStateOf(false)
private set

open suspend fun verify() {
if (!destination.exists())
Expand All @@ -46,6 +54,11 @@ abstract class DownloadStep: Step() {
runner.logger.i("Checking if $fileName isn't empty")
if (destination.length() > 0) {
runner.logger.i("vendetta.apk is cached")
cached = true

runner.logger.i("Moving $fileName to working directory")
destination.copyTo(workingCopy, true)

status = StepStatus.SUCCESSFUL
return
}
Expand All @@ -55,9 +68,13 @@ abstract class DownloadStep: Step() {
}

runner.logger.i("$fileName was not properly cached, downloading now")
var lastProgress: Float? = null
val result = downloadManager.download(url, destination) { newProgress ->
progress = newProgress
runner.logger.d("$fileName download progress: $newProgress")
if (newProgress != lastProgress && newProgress != null) {
lastProgress = newProgress
runner.logger.d("$fileName download progress: ${(lastProgress!! * 100f).roundToInt()}%")
}
}

when (result) {
Expand All @@ -66,6 +83,9 @@ abstract class DownloadStep: Step() {
runner.logger.i("Verifying downloaded file")
verify()
runner.logger.i("$fileName downloaded successfully")

runner.logger.i("Moving $fileName to working directory")
destination.copyTo(workingCopy, true)
} catch (t: Throwable) {
mainThread {
context.showToast(R.string.msg_download_verify_failed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AddVendettaStep(
override val nameRes = R.string.step_add_vd

override suspend fun run(runner: StepRunner) {
val vendetta = runner.getCompletedStep<DownloadVendettaStep>().destination
val vendetta = runner.getCompletedStep<DownloadVendettaStep>().workingCopy

runner.logger.i("Adding Vendetta module with LSPatch")
val files = signedDir.listFiles()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class PatchManifestsStep : Step() {
override val nameRes = R.string.step_patch_manifests

override suspend fun run(runner: StepRunner) {
val baseApk = runner.getCompletedStep<DownloadBaseStep>().destination
val libsApk = runner.getCompletedStep<DownloadLibsStep>().destination
val langApk = runner.getCompletedStep<DownloadLangStep>().destination
val resApk = runner.getCompletedStep<DownloadResourcesStep>().destination
val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy
val libsApk = runner.getCompletedStep<DownloadLibsStep>().workingCopy
val langApk = runner.getCompletedStep<DownloadLangStep>().workingCopy
val resApk = runner.getCompletedStep<DownloadResourcesStep>().workingCopy

arrayOf(baseApk, libsApk, langApk, resApk).forEach { apk ->
runner.logger.i("Reading AndroidManifest.xml from ${apk.name}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ import com.github.diamondminer88.zip.ZipCompression
import com.github.diamondminer88.zip.ZipReader
import com.github.diamondminer88.zip.ZipWriter
import dev.beefers.vendetta.manager.R
import dev.beefers.vendetta.manager.domain.manager.PreferenceManager
import dev.beefers.vendetta.manager.installer.step.Step
import dev.beefers.vendetta.manager.installer.step.StepGroup
import dev.beefers.vendetta.manager.installer.step.StepRunner
import dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep
import dev.beefers.vendetta.manager.installer.step.download.DownloadLangStep
import dev.beefers.vendetta.manager.installer.step.download.DownloadLibsStep
import dev.beefers.vendetta.manager.installer.step.download.DownloadResourcesStep
import dev.beefers.vendetta.manager.installer.util.ManifestPatcher
import dev.beefers.vendetta.manager.installer.util.Signer
import org.koin.core.component.inject
import java.io.File

class PresignApksStep(
Expand All @@ -26,10 +23,10 @@ class PresignApksStep(
override val nameRes = R.string.step_signing

override suspend fun run(runner: StepRunner) {
val baseApk = runner.getCompletedStep<DownloadBaseStep>().destination
val libsApk = runner.getCompletedStep<DownloadLibsStep>().destination
val langApk = runner.getCompletedStep<DownloadLangStep>().destination
val resApk = runner.getCompletedStep<DownloadResourcesStep>().destination
val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy
val libsApk = runner.getCompletedStep<DownloadLibsStep>().workingCopy
val langApk = runner.getCompletedStep<DownloadLangStep>().workingCopy
val resApk = runner.getCompletedStep<DownloadResourcesStep>().workingCopy

runner.logger.i("Creating dir for signed apks: ${signedDir.absolutePath}")
signedDir.mkdirs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ReplaceIconStep : Step() {
override val nameRes = R.string.step_change_icon

override suspend fun run(runner: StepRunner) {
val baseApk = runner.getCompletedStep<DownloadBaseStep>().destination
val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy

ZipWriter(baseApk, true).use { apk ->
runner.logger.i("Replacing icons in ${baseApk.name}")
Expand Down
Loading

0 comments on commit 46a7d04

Please sign in to comment.