From 8f41b2e284581161a02c22ba2712631522eec758 Mon Sep 17 00:00:00 2001 From: Canny Date: Sun, 9 Oct 2022 18:47:12 +0300 Subject: [PATCH] fix: duped apps in app selector --- .../java/app/revanced/manager/Variables.kt | 1 - .../app/revanced/manager/patcher/aapt/Aapt.kt | 4 ++-- .../manager/patcher/worker/PatcherWorker.kt | 15 +++++++----- .../screen/subscreens/AppSelectorSubscreen.kt | 23 +++++++++---------- .../ui/viewmodel/AppSelectorViewModel.kt | 18 +++++++++------ 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/Variables.kt b/app/src/main/java/app/revanced/manager/Variables.kt index 64f15f5..efb0a2a 100644 --- a/app/src/main/java/app/revanced/manager/Variables.kt +++ b/app/src/main/java/app/revanced/manager/Variables.kt @@ -15,5 +15,4 @@ object Variables { val selectedPatches = mutableStateListOf() val patches = mutableStateOf>>>>(Resource.Loading) val patchesState by patches - val filteredApps = mutableListOf() } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/patcher/aapt/Aapt.kt b/app/src/main/java/app/revanced/manager/patcher/aapt/Aapt.kt index f0fea12..3ec8489 100644 --- a/app/src/main/java/app/revanced/manager/patcher/aapt/Aapt.kt +++ b/app/src/main/java/app/revanced/manager/patcher/aapt/Aapt.kt @@ -4,9 +4,9 @@ import android.content.Context import java.io.File object Aapt { - fun binary(context: Context): File { + fun binary(context: Context): File? { return File(context.applicationInfo.nativeLibraryDir).resolveAapt() } } -private fun File.resolveAapt() = resolve(list { _, f -> !File(f).isDirectory }!!.first()) \ No newline at end of file +private fun File.resolveAapt() = list { _, f -> !File(f).isDirectory }?.firstOrNull()?.let { resolve(it) } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt index 28982c2..c950829 100644 --- a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt +++ b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.koin.core.component.KoinComponent import java.io.File +import java.io.FileNotFoundException import java.nio.file.Files import java.nio.file.StandardCopyOption @@ -89,7 +90,11 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val private suspend fun runPatcher( workdir: File ): Boolean { - val aaptPath = Aapt.binary(applicationContext).absolutePath + val aaptPath = Aapt.binary(applicationContext)?.absolutePath + if (aaptPath == null) { + Logging.log += "AAPT2 not found.\n" + throw FileNotFoundException() + } val frameworkPath = applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath val integrationsCacheDir = @@ -162,14 +167,10 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val } } + Logging.log += "Saving file\n" - val result = patcher.save() // compile apk - if (patchedFile.exists()) withContext(Dispatchers.IO) { - Files.delete(patchedFile.toPath()) - } - ZipFile(patchedFile).use { fs -> // somehow this function is the most resource intensive result.dexFiles.forEach { Logging.log += "Writing dex file ${it.name}\n" @@ -198,6 +199,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val return patches.filter { patch -> ids.any { it == patch.patchName } } } + + private fun createWorkDir(): File { return applicationContext.filesDir.resolve("tmp-${System.currentTimeMillis()}") .also { it.mkdirs() } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/subscreens/AppSelectorSubscreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/subscreens/AppSelectorSubscreen.kt index 04db06b..518098c 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/subscreens/AppSelectorSubscreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/subscreens/AppSelectorSubscreen.kt @@ -12,13 +12,11 @@ import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.SdStorage import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf 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.Variables.filteredApps -import app.revanced.manager.Variables.patchesState -import app.revanced.manager.ui.Resource import app.revanced.manager.ui.component.AppIcon import app.revanced.manager.ui.component.LoadingIndicator import app.revanced.manager.ui.navigation.AppDestination @@ -27,7 +25,7 @@ import com.xinto.taxi.BackstackNavigator import org.koin.androidx.compose.getViewModel @OptIn(ExperimentalMaterial3Api::class) -@SuppressLint("QueryPermissionsNeeded") +@SuppressLint("QueryPermissionsNeeded", "UnrememberedMutableState") @Composable fun AppSelectorSubscreen( navigator: BackstackNavigator, @@ -35,7 +33,9 @@ fun AppSelectorSubscreen( ) { val context = LocalContext.current - val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { + val filtered = mutableStateOf(vm.filteredApps.isNotEmpty()) + + val filePicker = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { it?.let { uri -> vm.setSelectedAppPackageFromFile(uri) navigator.pop() @@ -55,17 +55,17 @@ fun AppSelectorSubscreen( }, floatingActionButton = { ExtendedFloatingActionButton( - onClick = { launcher.launch(arrayOf("application/vnd.android.package-archive")) }, + onClick = { + filePicker.launch(arrayOf("application/vnd.android.package-archive")) }, icon = { Icon(Icons.Default.SdStorage, contentDescription = null) }, text = { Text("Storage") }, ) }, ) { paddingValues -> - when (patchesState) { - is Resource.Success -> { + if (filtered.value) { LazyColumn(modifier = Modifier.padding(paddingValues)) { - items(count = filteredApps.size) { - val app = filteredApps.distinct()[it] + items(count = vm.filteredApps.size) { int -> + val app = vm.filteredApps[int] val label = vm.applicationLabel(app) val packageName = app.packageName @@ -88,8 +88,7 @@ fun AppSelectorSubscreen( }) } } - } - else -> LoadingIndicator(null) } + else LoadingIndicator(null) } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt index 23fe3e5..8e3fc69 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/AppSelectorViewModel.kt @@ -7,12 +7,14 @@ import android.graphics.drawable.Drawable import android.net.Uri import android.util.Log import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import app.revanced.manager.Variables -import app.revanced.manager.Variables.filteredApps import app.revanced.manager.Variables.patches import app.revanced.manager.Variables.selectedAppPackage import app.revanced.manager.ui.Resource +import app.revanced.manager.util.tag import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages +import kotlinx.coroutines.launch import java.nio.file.Files import java.nio.file.StandardCopyOption import java.util.* @@ -21,18 +23,20 @@ class AppSelectorViewModel( val app: Application, ) : ViewModel() { + val filteredApps = mutableListOf() + init { - filterApps() + viewModelScope.launch { filterApps() } } - private fun filterApps(): List { + private fun filterApps() { try { val (patches) = patches.value as Resource.Success patches.forEach patch@{ patch -> patch.compatiblePackages?.forEach { pkg -> try { - val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0) - if (!filteredApps.contains(appInfo)) { + if (!(filteredApps.any { it.packageName == pkg.name })) { + val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0) filteredApps.add(appInfo) return@forEach } @@ -41,10 +45,10 @@ class AppSelectorViewModel( } } } + Log.d(tag, "Filtered apps.") } catch (e: Exception) { - Log.e("ReVanced Manager", "An error occurred while filtering", e) + Log.e(tag, "An error occurred while filtering", e) } - return emptyList() } fun applicationLabel(info: ApplicationInfo): String {