mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
fix: delete temporary files (#1341)
This commit is contained in:
parent
abf4d91703
commit
723f9cd98c
@ -9,9 +9,18 @@ import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import app.revanced.manager.util.RequestManageStorageContract
|
||||
|
||||
class FileSystem(private val app: Application) {
|
||||
class Filesystem(private val app: Application) {
|
||||
val contentResolver = app.contentResolver // TODO: move Content Resolver operations to here.
|
||||
|
||||
/**
|
||||
* A directory that gets cleared when the app restarts.
|
||||
* Do not store paths to this directory in a parcel.
|
||||
*/
|
||||
val tempDir = app.cacheDir.resolve("ephemeral").apply {
|
||||
deleteRecursively()
|
||||
mkdirs()
|
||||
}
|
||||
|
||||
fun externalFilesDir() = Environment.getExternalStorageDirectory().toPath()
|
||||
|
||||
private fun usesManagePermission() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
@ -1,17 +1,20 @@
|
||||
package app.revanced.manager.di
|
||||
|
||||
import app.revanced.manager.data.platform.FileSystem
|
||||
import app.revanced.manager.data.platform.Filesystem
|
||||
import app.revanced.manager.data.platform.NetworkInfo
|
||||
import app.revanced.manager.domain.repository.*
|
||||
import app.revanced.manager.domain.worker.WorkerRepository
|
||||
import app.revanced.manager.network.api.ReVancedAPI
|
||||
import org.koin.core.module.dsl.createdAtStart
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.module
|
||||
|
||||
val repositoryModule = module {
|
||||
singleOf(::ReVancedAPI)
|
||||
singleOf(::GithubRepository)
|
||||
singleOf(::FileSystem)
|
||||
singleOf(::Filesystem) {
|
||||
createdAtStart()
|
||||
}
|
||||
singleOf(::NetworkInfo)
|
||||
singleOf(::PatchBundlePersistenceRepository)
|
||||
singleOf(::PatchSelectionRepository)
|
||||
|
@ -24,16 +24,17 @@ class Session(
|
||||
private val input: File,
|
||||
private val onStepSucceeded: suspend () -> Unit
|
||||
) : Closeable {
|
||||
private val temporary = File(cacheDir).resolve("manager").also { it.mkdirs() }
|
||||
private val tempDir = File(cacheDir).resolve("patcher").also { it.mkdirs() }
|
||||
private val patcher = Patcher(
|
||||
PatcherOptions(
|
||||
inputFile = input,
|
||||
resourceCachePath = temporary.resolve("aapt-resources"),
|
||||
resourceCachePath = tempDir.resolve("aapt-resources"),
|
||||
frameworkFileDirectory = frameworkDir,
|
||||
aaptBinaryPath = aaptPath
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
private suspend fun Patcher.applyPatchesVerbose() {
|
||||
this.apply(true).collect { (patch, exception) ->
|
||||
if (exception == null) {
|
||||
@ -70,7 +71,7 @@ class Session(
|
||||
logger.info("Writing patched files...")
|
||||
val result = patcher.get()
|
||||
|
||||
val aligned = temporary.resolve("aligned.apk")
|
||||
val aligned = tempDir.resolve("aligned.apk")
|
||||
ApkUtils.copyAligned(input, aligned, result)
|
||||
|
||||
logger.info("Patched apk saved to $aligned")
|
||||
@ -82,7 +83,7 @@ class Session(
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
temporary.delete()
|
||||
tempDir.deleteRecursively()
|
||||
patcher.close()
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.work.ForegroundInfo
|
||||
import androidx.work.WorkerParameters
|
||||
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.PreferencesManager
|
||||
@ -49,6 +50,7 @@ class PatcherWorker(
|
||||
private val prefs: PreferencesManager by inject()
|
||||
private val downloadedAppRepository: DownloadedAppRepository by inject()
|
||||
private val pm: PM by inject()
|
||||
private val fs: Filesystem by inject()
|
||||
private val installedAppRepository: InstalledAppRepository by inject()
|
||||
private val rootInstaller: RootInstaller by inject()
|
||||
|
||||
@ -57,13 +59,12 @@ class PatcherWorker(
|
||||
val output: String,
|
||||
val selectedPatches: PatchesSelection,
|
||||
val options: Options,
|
||||
val packageName: String,
|
||||
val packageVersion: String,
|
||||
val progress: MutableStateFlow<ImmutableList<Step>>,
|
||||
val logger: ManagerLogger,
|
||||
val selectedApp: SelectedApp,
|
||||
val setInputFile: (File) -> Unit
|
||||
)
|
||||
) {
|
||||
val packageName get() = input.packageName
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val logPrefix = "[Worker]:"
|
||||
@ -153,7 +154,7 @@ class PatcherWorker(
|
||||
|
||||
return try {
|
||||
|
||||
if (args.selectedApp is SelectedApp.Installed) {
|
||||
if (args.input is SelectedApp.Installed) {
|
||||
installedAppRepository.get(args.packageName)?.let {
|
||||
if (it.installType == InstallType.ROOT) {
|
||||
rootInstaller.unmount(args.packageName)
|
||||
@ -212,7 +213,7 @@ class PatcherWorker(
|
||||
}
|
||||
|
||||
Session(
|
||||
applicationContext.cacheDir.absolutePath,
|
||||
fs.tempDir.absolutePath,
|
||||
frameworkPath,
|
||||
aaptPath,
|
||||
args.logger,
|
||||
|
@ -26,7 +26,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.data.platform.FileSystem
|
||||
import app.revanced.manager.data.platform.Filesystem
|
||||
import app.revanced.manager.patcher.patch.Option
|
||||
import app.revanced.manager.util.toast
|
||||
import app.revanced.patcher.patch.options.types.*
|
||||
@ -61,7 +61,7 @@ private fun StringOptionDialog(
|
||||
mutableStateOf(value.orEmpty())
|
||||
}
|
||||
|
||||
val fs: FileSystem = rememberKoinInject()
|
||||
val fs: Filesystem = rememberKoinInject()
|
||||
val (contract, permissionName) = fs.permissionContract()
|
||||
val permissionLauncher = rememberLauncherForActivityResult(contract = contract) {
|
||||
showFileDialog = it
|
||||
|
@ -13,7 +13,7 @@ sealed class SelectedApp : Parcelable {
|
||||
data class Download(override val packageName: String, override val version: String, val app: AppDownloader.App) : SelectedApp()
|
||||
|
||||
@Parcelize
|
||||
data class Local(override val packageName: String, override val version: String, val file: File) : SelectedApp()
|
||||
data class Local(override val packageName: String, override val version: String, val file: File, val shouldDelete: Boolean) : SelectedApp()
|
||||
|
||||
@Parcelize
|
||||
data class Installed(override val packageName: String, override val version: String) : SelectedApp()
|
||||
|
@ -13,19 +13,26 @@ class AppSelectorViewModel(
|
||||
private val app: Application,
|
||||
private val pm: PM
|
||||
) : ViewModel() {
|
||||
private val inputFile = File(app.cacheDir, "input.apk").also {
|
||||
it.delete()
|
||||
}
|
||||
val appList = pm.appList
|
||||
|
||||
fun loadLabel(app: PackageInfo?) = with(pm) { app?.label() ?: "Not installed" }
|
||||
|
||||
fun loadSelectedFile(uri: Uri) =
|
||||
app.contentResolver.openInputStream(uri)?.use { stream ->
|
||||
File(app.cacheDir, "input.apk").also {
|
||||
it.delete()
|
||||
Files.copy(stream, it.toPath())
|
||||
}.let { file ->
|
||||
pm.getPackageInfo(file)
|
||||
?.let { packageInfo ->
|
||||
SelectedApp.Local(packageName = packageInfo.packageName, version = packageInfo.versionName, file = file)
|
||||
with(inputFile) {
|
||||
delete()
|
||||
Files.copy(stream, toPath())
|
||||
|
||||
pm.getPackageInfo(this)?.let { packageInfo ->
|
||||
SelectedApp.Local(
|
||||
packageName = packageInfo.packageName,
|
||||
version = packageInfo.versionName,
|
||||
file = this,
|
||||
shouldDelete = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
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.data.room.apps.installed.InstalledApp
|
||||
import app.revanced.manager.domain.installer.RootInstaller
|
||||
@ -57,16 +58,22 @@ class InstallerViewModel(
|
||||
) : 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()
|
||||
private val workerRepository: WorkerRepository by inject()
|
||||
private val installedAppRepository: InstalledAppRepository by inject()
|
||||
private val rootInstaller: RootInstaller by inject()
|
||||
|
||||
val packageName: String = input.selectedApp.packageName
|
||||
private val outputFile = File(app.cacheDir, "output.apk")
|
||||
private val signedFile = File(app.cacheDir, "signed.apk").also { if (it.exists()) it.delete() }
|
||||
private val tempDir = fs.tempDir.resolve("installer").also {
|
||||
it.deleteRecursively()
|
||||
it.mkdirs()
|
||||
}
|
||||
|
||||
private val outputFile = tempDir.resolve("output.apk")
|
||||
private val signedFile = tempDir.resolve("signed.apk")
|
||||
private var hasSigned = false
|
||||
var inputFile: File? = null
|
||||
private var inputFile: File? = null
|
||||
|
||||
private var installedApp: InstalledApp? = null
|
||||
var isInstalling by mutableStateOf(false)
|
||||
@ -82,6 +89,8 @@ class InstallerViewModel(
|
||||
private val logger = ManagerLogger()
|
||||
|
||||
init {
|
||||
// TODO: navigate away when system-initiated process death is detected because it is not possible to recover from it.
|
||||
|
||||
viewModelScope.launch {
|
||||
installedApp = installedAppRepository.get(packageName)
|
||||
}
|
||||
@ -101,11 +110,8 @@ class InstallerViewModel(
|
||||
outputFile.path,
|
||||
patches,
|
||||
options,
|
||||
packageName,
|
||||
selectedApp.version,
|
||||
_progress,
|
||||
logger,
|
||||
selectedApp,
|
||||
setInputFile = { inputFile = it }
|
||||
)
|
||||
)
|
||||
@ -176,8 +182,14 @@ class InstallerViewModel(
|
||||
app.unregisterReceiver(installBroadcastReceiver)
|
||||
workManager.cancelWorkById(patcherWorkerId)
|
||||
|
||||
outputFile.delete()
|
||||
signedFile.delete()
|
||||
when (val selectedApp = input.selectedApp) {
|
||||
is SelectedApp.Local -> {
|
||||
if (selectedApp.shouldDelete) selectedApp.file.delete()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
tempDir.deleteRecursively()
|
||||
|
||||
try {
|
||||
if (input.selectedApp is SelectedApp.Installed) {
|
||||
|
@ -68,7 +68,7 @@ class VersionSelectorViewModel(
|
||||
}
|
||||
|
||||
val downloadedVersions = downloadedAppRepository.getAll().map { downloadedApps ->
|
||||
downloadedApps.filter { it.packageName == packageName }.map { SelectedApp.Local(it.packageName, it.version, it.file) }
|
||||
downloadedApps.filter { it.packageName == packageName }.map { SelectedApp.Local(it.packageName, it.version, it.file, false) }
|
||||
}
|
||||
|
||||
init {
|
||||
|
Loading…
Reference in New Issue
Block a user