fix: duped apps in app selector

This commit is contained in:
Canny 2022-10-09 18:47:12 +03:00
parent d537375758
commit 8f41b2e284
No known key found for this signature in database
GPG Key ID: 395CCB0AA979F27B
5 changed files with 33 additions and 28 deletions

View File

@ -15,5 +15,4 @@ object Variables {
val selectedPatches = mutableStateListOf<String>() val selectedPatches = mutableStateListOf<String>()
val patches = mutableStateOf<Resource<List<Class<out Patch<Context>>>>>(Resource.Loading) val patches = mutableStateOf<Resource<List<Class<out Patch<Context>>>>>(Resource.Loading)
val patchesState by patches val patchesState by patches
val filteredApps = mutableListOf<ApplicationInfo>()
} }

View File

@ -4,9 +4,9 @@ import android.content.Context
import java.io.File import java.io.File
object Aapt { object Aapt {
fun binary(context: Context): File { fun binary(context: Context): File? {
return File(context.applicationInfo.nativeLibraryDir).resolveAapt() return File(context.applicationInfo.nativeLibraryDir).resolveAapt()
} }
} }
private fun File.resolveAapt() = resolve(list { _, f -> !File(f).isDirectory }!!.first()) private fun File.resolveAapt() = list { _, f -> !File(f).isDirectory }?.firstOrNull()?.let { resolve(it) }

View File

@ -33,6 +33,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import java.io.File import java.io.File
import java.io.FileNotFoundException
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
@ -89,7 +90,11 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
private suspend fun runPatcher( private suspend fun runPatcher(
workdir: File workdir: File
): Boolean { ): 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 = val frameworkPath =
applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath
val integrationsCacheDir = val integrationsCacheDir =
@ -162,14 +167,10 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
} }
} }
Logging.log += "Saving file\n" Logging.log += "Saving file\n"
val result = patcher.save() // compile apk 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 ZipFile(patchedFile).use { fs -> // somehow this function is the most resource intensive
result.dexFiles.forEach { result.dexFiles.forEach {
Logging.log += "Writing dex file ${it.name}\n" 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 } } return patches.filter { patch -> ids.any { it == patch.patchName } }
} }
private fun createWorkDir(): File { private fun createWorkDir(): File {
return applicationContext.filesDir.resolve("tmp-${System.currentTimeMillis()}") return applicationContext.filesDir.resolve("tmp-${System.currentTimeMillis()}")
.also { it.mkdirs() } .also { it.mkdirs() }

View File

@ -12,13 +12,11 @@ import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.SdStorage import androidx.compose.material.icons.filled.SdStorage
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import app.revanced.manager.R 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.AppIcon
import app.revanced.manager.ui.component.LoadingIndicator import app.revanced.manager.ui.component.LoadingIndicator
import app.revanced.manager.ui.navigation.AppDestination import app.revanced.manager.ui.navigation.AppDestination
@ -27,7 +25,7 @@ import com.xinto.taxi.BackstackNavigator
import org.koin.androidx.compose.getViewModel import org.koin.androidx.compose.getViewModel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("QueryPermissionsNeeded") @SuppressLint("QueryPermissionsNeeded", "UnrememberedMutableState")
@Composable @Composable
fun AppSelectorSubscreen( fun AppSelectorSubscreen(
navigator: BackstackNavigator<AppDestination>, navigator: BackstackNavigator<AppDestination>,
@ -35,7 +33,9 @@ fun AppSelectorSubscreen(
) { ) {
val context = LocalContext.current val context = LocalContext.current
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { val filtered = mutableStateOf(vm.filteredApps.isNotEmpty())
val filePicker = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
it?.let { uri -> it?.let { uri ->
vm.setSelectedAppPackageFromFile(uri) vm.setSelectedAppPackageFromFile(uri)
navigator.pop() navigator.pop()
@ -55,17 +55,17 @@ fun AppSelectorSubscreen(
}, },
floatingActionButton = { floatingActionButton = {
ExtendedFloatingActionButton( 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) }, icon = { Icon(Icons.Default.SdStorage, contentDescription = null) },
text = { Text("Storage") }, text = { Text("Storage") },
) )
}, },
) { paddingValues -> ) { paddingValues ->
when (patchesState) { if (filtered.value) {
is Resource.Success -> {
LazyColumn(modifier = Modifier.padding(paddingValues)) { LazyColumn(modifier = Modifier.padding(paddingValues)) {
items(count = filteredApps.size) { items(count = vm.filteredApps.size) { int ->
val app = filteredApps.distinct()[it] val app = vm.filteredApps[int]
val label = vm.applicationLabel(app) val label = vm.applicationLabel(app)
val packageName = app.packageName val packageName = app.packageName
@ -89,7 +89,6 @@ fun AppSelectorSubscreen(
} }
} }
} }
else -> LoadingIndicator(null) else LoadingIndicator(null)
}
} }
} }

View File

@ -7,12 +7,14 @@ import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.revanced.manager.Variables import app.revanced.manager.Variables
import app.revanced.manager.Variables.filteredApps
import app.revanced.manager.Variables.patches import app.revanced.manager.Variables.patches
import app.revanced.manager.Variables.selectedAppPackage import app.revanced.manager.Variables.selectedAppPackage
import app.revanced.manager.ui.Resource import app.revanced.manager.ui.Resource
import app.revanced.manager.util.tag
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import kotlinx.coroutines.launch
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import java.util.* import java.util.*
@ -21,18 +23,20 @@ class AppSelectorViewModel(
val app: Application, val app: Application,
) : ViewModel() { ) : ViewModel() {
val filteredApps = mutableListOf<ApplicationInfo>()
init { init {
filterApps() viewModelScope.launch { filterApps() }
} }
private fun filterApps(): List<ApplicationInfo> { private fun filterApps() {
try { try {
val (patches) = patches.value as Resource.Success val (patches) = patches.value as Resource.Success
patches.forEach patch@{ patch -> patches.forEach patch@{ patch ->
patch.compatiblePackages?.forEach { pkg -> patch.compatiblePackages?.forEach { pkg ->
try { try {
if (!(filteredApps.any { it.packageName == pkg.name })) {
val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0) val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0)
if (!filteredApps.contains(appInfo)) {
filteredApps.add(appInfo) filteredApps.add(appInfo)
return@forEach return@forEach
} }
@ -41,10 +45,10 @@ class AppSelectorViewModel(
} }
} }
} }
Log.d(tag, "Filtered apps.")
} catch (e: Exception) { } 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 { fun applicationLabel(info: ApplicationInfo): String {