mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat(installer): sign apk in patcher worker
This commit is contained in:
parent
7d887c73e8
commit
172604fcdb
@ -26,7 +26,12 @@ class Step(
|
||||
val state: State = State.WAITING
|
||||
)
|
||||
|
||||
class PatcherProgressManager(context: Context, selectedPatches: List<String>, selectedApp: SelectedApp, downloadProgress: StateFlow<Pair<Float, Float>?>) {
|
||||
class PatcherProgressManager(
|
||||
context: Context,
|
||||
selectedPatches: List<String>,
|
||||
selectedApp: SelectedApp,
|
||||
downloadProgress: StateFlow<Pair<Float, Float>?>
|
||||
) {
|
||||
val steps = generateSteps(context, selectedPatches, selectedApp, downloadProgress)
|
||||
private var currentStep: StepKey? = StepKey(0, 0)
|
||||
|
||||
@ -87,12 +92,20 @@ class PatcherProgressManager(context: Context, selectedPatches: List<String>, se
|
||||
selectedPatches.map { SubStep(it) }.toImmutableList()
|
||||
)
|
||||
|
||||
fun generateSteps(context: Context, selectedPatches: List<String>, selectedApp: SelectedApp, downloadProgress: StateFlow<Pair<Float, Float>?>? = null) = mutableListOf(
|
||||
fun generateSteps(
|
||||
context: Context,
|
||||
selectedPatches: List<String>,
|
||||
selectedApp: SelectedApp,
|
||||
downloadProgress: StateFlow<Pair<Float, Float>?>? = null
|
||||
) = mutableListOf(
|
||||
Step(
|
||||
R.string.patcher_step_group_prepare,
|
||||
listOfNotNull(
|
||||
SubStep(context.getString(R.string.patcher_step_load_patches)),
|
||||
SubStep("Download apk", progress = downloadProgress).takeIf { selectedApp is SelectedApp.Download },
|
||||
SubStep(
|
||||
"Download apk",
|
||||
progress = downloadProgress
|
||||
).takeIf { selectedApp is SelectedApp.Download },
|
||||
SubStep(context.getString(R.string.patcher_step_unpack)),
|
||||
SubStep(context.getString(R.string.patcher_step_integrations))
|
||||
).toImmutableList()
|
||||
@ -100,7 +113,10 @@ class PatcherProgressManager(context: Context, selectedPatches: List<String>, se
|
||||
generatePatchesStep(selectedPatches),
|
||||
Step(
|
||||
R.string.patcher_step_group_saving,
|
||||
persistentListOf(SubStep(context.getString(R.string.patcher_step_write_patched)))
|
||||
persistentListOf(
|
||||
SubStep(context.getString(R.string.patcher_step_write_patched)),
|
||||
SubStep(context.getString(R.string.patcher_step_sign_apk))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import app.revanced.manager.R
|
||||
import app.revanced.manager.data.platform.Filesystem
|
||||
import app.revanced.manager.data.room.apps.installed.InstallType
|
||||
import app.revanced.manager.domain.installer.RootInstaller
|
||||
import app.revanced.manager.domain.manager.KeystoreManager
|
||||
import app.revanced.manager.domain.manager.PreferencesManager
|
||||
import app.revanced.manager.domain.repository.DownloadedAppRepository
|
||||
import app.revanced.manager.domain.repository.InstalledAppRepository
|
||||
@ -50,6 +51,7 @@ class PatcherWorker(
|
||||
private val patchBundleRepository: PatchBundleRepository by inject()
|
||||
private val workerRepository: WorkerRepository by inject()
|
||||
private val prefs: PreferencesManager by inject()
|
||||
private val keystoreManager: KeystoreManager by inject()
|
||||
private val downloadedAppRepository: DownloadedAppRepository by inject()
|
||||
private val pm: PM by inject()
|
||||
private val fs: Filesystem by inject()
|
||||
@ -159,6 +161,8 @@ class PatcherWorker(
|
||||
progressFlow.value = progressManager.getProgress().toImmutableList()
|
||||
}
|
||||
|
||||
val patchedApk = fs.tempDir.resolve("patched.apk")
|
||||
|
||||
return try {
|
||||
|
||||
if (args.input is SelectedApp.Installed) {
|
||||
@ -219,9 +223,12 @@ class PatcherWorker(
|
||||
inputFile,
|
||||
onStepSucceeded = ::updateProgress
|
||||
).use { session ->
|
||||
session.run(File(args.output), patches, integrations)
|
||||
session.run(patchedApk, patches, integrations)
|
||||
}
|
||||
|
||||
keystoreManager.sign(patchedApk, File(args.output))
|
||||
updateProgress() // Signing
|
||||
|
||||
Log.i(tag, "Patching succeeded".logFmt())
|
||||
progressManager.success()
|
||||
Result.success()
|
||||
@ -231,6 +238,7 @@ class PatcherWorker(
|
||||
Result.failure()
|
||||
} finally {
|
||||
updateProgress(false)
|
||||
patchedApk.delete()
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import app.revanced.manager.data.platform.Filesystem
|
||||
import app.revanced.manager.data.room.apps.installed.InstallType
|
||||
import app.revanced.manager.data.room.apps.installed.InstalledApp
|
||||
import app.revanced.manager.domain.installer.RootInstaller
|
||||
import app.revanced.manager.domain.manager.KeystoreManager
|
||||
import app.revanced.manager.domain.repository.InstalledAppRepository
|
||||
import app.revanced.manager.domain.worker.WorkerRepository
|
||||
import app.revanced.manager.patcher.worker.PatcherProgressManager
|
||||
@ -57,7 +56,6 @@ import java.util.logging.LogRecord
|
||||
class InstallerViewModel(
|
||||
private val input: Destination.Installer
|
||||
) : ViewModel(), KoinComponent {
|
||||
private val keystoreManager: KeystoreManager by inject()
|
||||
private val app: Application by inject()
|
||||
private val fs: Filesystem by inject()
|
||||
private val pm: PM by inject()
|
||||
@ -72,8 +70,6 @@ class InstallerViewModel(
|
||||
}
|
||||
|
||||
private val outputFile = tempDir.resolve("output.apk")
|
||||
private val signedFile = tempDir.resolve("signed.apk")
|
||||
private var hasSigned = false
|
||||
private var inputFile: File? = null
|
||||
|
||||
private var installedApp: InstalledApp? = null
|
||||
@ -209,42 +205,22 @@ class InstallerViewModel(
|
||||
tempDir.deleteRecursively()
|
||||
}
|
||||
|
||||
private suspend fun signApk(): Boolean {
|
||||
if (!hasSigned) {
|
||||
try {
|
||||
withContext(Dispatchers.Default) {
|
||||
keystoreManager.sign(outputFile, signedFile)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "Got exception while signing", e)
|
||||
app.toast(app.getString(R.string.sign_fail, e::class.simpleName))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun export(uri: Uri?) = viewModelScope.launch {
|
||||
uri?.let {
|
||||
if (signApk()) {
|
||||
withContext(Dispatchers.IO) {
|
||||
app.contentResolver.openOutputStream(it)
|
||||
.use { stream -> Files.copy(signedFile.toPath(), stream) }
|
||||
.use { stream -> Files.copy(outputFile.toPath(), stream) }
|
||||
}
|
||||
app.toast(app.getString(R.string.export_app_success))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun install(installType: InstallType) = viewModelScope.launch {
|
||||
isInstalling = true
|
||||
try {
|
||||
if (!signApk()) return@launch
|
||||
|
||||
when (installType) {
|
||||
InstallType.DEFAULT -> {
|
||||
pm.installApp(listOf(signedFile))
|
||||
pm.installApp(listOf(outputFile))
|
||||
}
|
||||
|
||||
InstallType.ROOT -> {
|
||||
@ -262,7 +238,7 @@ class InstallerViewModel(
|
||||
private suspend fun installAsRoot() {
|
||||
try {
|
||||
val label = with(pm) {
|
||||
getPackageInfo(signedFile)?.label()
|
||||
getPackageInfo(outputFile)?.label()
|
||||
?: throw Exception("Failed to load application info")
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,7 @@
|
||||
<string name="patcher_step_group_patching">Patching</string>
|
||||
<string name="patcher_step_group_saving">Saving</string>
|
||||
<string name="patcher_step_write_patched">Write patched Apk</string>
|
||||
<string name="patcher_step_sign_apk">Sign Apk</string>
|
||||
<string name="patcher_notification_message">Patching in progress…</string>
|
||||
|
||||
<string name="step_completed">completed</string>
|
||||
|
Loading…
Reference in New Issue
Block a user