diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ed323c5..f5622f1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -80,7 +80,7 @@ dependencies { implementation("androidx.core:core-splashscreen:1.0.0") // AndroidX activity - implementation("androidx.activity:activity-compose:1.6.0-rc02") + implementation("androidx.activity:activity-compose:1.6.0") implementation("androidx.work:work-runtime-ktx:2.7.1") // Koin @@ -93,7 +93,7 @@ dependencies { val composeVersion = "1.3.0-alpha03" implementation("androidx.compose.ui:ui:${composeVersion}") debugImplementation("androidx.compose.ui:ui-tooling:${composeVersion}") - implementation("androidx.compose.material3:material3:1.0.0-beta02") + implementation("androidx.compose.material3:material3:1.0.0-beta03") implementation("androidx.compose.material:material-icons-extended:${composeVersion}") // Accompanist @@ -134,5 +134,5 @@ dependencies { // ListenableFuture implementation("com.google.guava:guava:31.0.1-android") implementation("androidx.concurrent:concurrent-futures:1.1.0") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.4") } diff --git a/app/src/main/java/app/revanced/manager/Variables.kt b/app/src/main/java/app/revanced/manager/Variables.kt index 2623490..64f15f5 100644 --- a/app/src/main/java/app/revanced/manager/Variables.kt +++ b/app/src/main/java/app/revanced/manager/Variables.kt @@ -11,7 +11,7 @@ import java.util.* object Variables { - val selectedAppPackage = mutableStateOf(Optional.empty()) + val selectedAppPackage = mutableStateOf(Optional.empty()) val selectedPatches = mutableStateListOf() val patches = mutableStateOf>>>>(Resource.Loading) val patchesState by patches 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 388f8b3..daced2c 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 @@ -89,7 +89,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath val integrationsCacheDir = applicationContext.filesDir.resolve("integrations-cache").also { it.mkdirs() } - val appInfo = applicationContext.packageManager.getApplicationInfo(selectedAppPackage.value.get(), 3) + val appInfo = selectedAppPackage.value.get() Logging.log += "Checking prerequisites\n" val patches = findPatchesByIds(selectedPatches) @@ -151,9 +151,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val Logging.log += "Applying ${patches.size} patch(es)\n" patcher.executePatches().forEach { (patch, result) -> - if (result.isFailure) { - Logging.log += "Failed to apply $patch \n" + result.exceptionOrNull()!!.message + Logging.log += "Failed to apply $patch" + result.exceptionOrNull()!!.cause + "\n" return@forEach } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt index 5edb69e..ecb372e 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt @@ -71,7 +71,10 @@ fun PatcherScreen( ) Text( text = if (patchesLoaded) { - selectedAppPackage.orElse(stringResource(R.string.card_application_not_selected)) + if (selectedAppPackage.isPresent) { + selectedAppPackage.get().packageName + } + else {stringResource(R.string.card_application_not_selected)} } else { stringResource(R.string.card_application_not_loaded) }, diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt index 326e8ed..32f2585 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt @@ -11,7 +11,6 @@ import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Done import androidx.compose.material3.* import androidx.compose.runtime.* -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow @@ -31,7 +30,7 @@ fun PatchingScreen( navigator: BackstackNavigator, vm: PatchingScreenViewModel = getViewModel() ) { - var patching by rememberSaveable {mutableStateOf(false)} + var patching by mutableStateOf(false) val scrollState = rememberScrollState() val coroutineScope = rememberCoroutineScope() LaunchedEffect(patching) { 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 c7ba613..04db06b 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 @@ -1,14 +1,19 @@ package app.revanced.manager.ui.screen.subscreens import android.annotation.SuppressLint +import android.widget.Toast +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons 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.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 @@ -28,32 +33,45 @@ fun AppSelectorSubscreen( navigator: BackstackNavigator, vm: AppSelectorViewModel = getViewModel(), ) { + val context = LocalContext.current + + val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { + it?.let { uri -> + vm.setSelectedAppPackageFromFile(uri) + navigator.pop() + return@rememberLauncherForActivityResult + } + Toast.makeText(context, "Couldn't load APK file.", Toast.LENGTH_SHORT).show() + } + Scaffold( topBar = { - MediumTopAppBar( - title = { Text(stringResource(R.string.app_selector_title)) }, + MediumTopAppBar(title = { Text(stringResource(R.string.app_selector_title)) }, navigationIcon = { IconButton(onClick = navigator::pop) { - Icon( - imageVector = Icons.Default.ArrowBack, - contentDescription = null - ) + Icon(Icons.Default.ArrowBack, contentDescription = null) } - }, + }) + }, + floatingActionButton = { + ExtendedFloatingActionButton( + onClick = { launcher.launch(arrayOf("application/vnd.android.package-archive")) }, + icon = { Icon(Icons.Default.SdStorage, contentDescription = null) }, + text = { Text("Storage") }, ) - } + }, ) { paddingValues -> when (patchesState) { is Resource.Success -> { LazyColumn(modifier = Modifier.padding(paddingValues)) { items(count = filteredApps.size) { - val app = filteredApps[it] + val app = filteredApps.distinct()[it] val label = vm.applicationLabel(app) val packageName = app.packageName val same = packageName == label ListItem(modifier = Modifier.clickable { - vm.setSelectedAppPackage(app.packageName) + vm.setSelectedAppPackage(app) navigator.pop() }, leadingContent = { AppIcon(vm.loadIcon(app), packageName) 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 f809f9c..23fe3e5 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 @@ -2,7 +2,9 @@ package app.revanced.manager.ui.viewmodel import android.app.Application import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager import android.graphics.drawable.Drawable +import android.net.Uri import android.util.Log import androidx.lifecycle.ViewModel import app.revanced.manager.Variables @@ -11,6 +13,8 @@ import app.revanced.manager.Variables.patches import app.revanced.manager.Variables.selectedAppPackage import app.revanced.manager.ui.Resource import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages +import java.nio.file.Files +import java.nio.file.StandardCopyOption import java.util.* class AppSelectorViewModel( @@ -28,7 +32,7 @@ class AppSelectorViewModel( patch.compatiblePackages?.forEach { pkg -> try { val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0) - if (appInfo !in filteredApps) { + if (!filteredApps.contains(appInfo)) { filteredApps.add(appInfo) return@forEach } @@ -51,11 +55,25 @@ class AppSelectorViewModel( return info.loadIcon(app.packageManager) } - fun setSelectedAppPackage(appId: String) { + fun setSelectedAppPackage(appId: ApplicationInfo) { selectedAppPackage.value.ifPresent { s -> if (s != appId) Variables.selectedPatches.clear() } selectedAppPackage.value = Optional.of(appId) + } + fun setSelectedAppPackageFromFile(file: Uri?) { + val apkDir = app.filesDir.resolve("input.apk").toPath() + Files.copy( + app.contentResolver.openInputStream(file!!), + apkDir, + StandardCopyOption.REPLACE_EXISTING + ) + setSelectedAppPackage( + app.packageManager.getPackageArchiveInfo( + apkDir.toString(), + PackageManager.GET_META_DATA + )!!.applicationInfo + ) } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherScreenViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherScreenViewModel.kt index 95065f1..3d0787f 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherScreenViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatcherScreenViewModel.kt @@ -1,6 +1,7 @@ package app.revanced.manager.ui.viewmodel import android.app.Application +import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.os.Parcelable import android.util.Log @@ -64,13 +65,15 @@ class PatcherScreenViewModel(private val app: Application, private val api: API) } - fun getSelectedPackageInfo() = - if (selectedAppPackage.value.isPresent) - app.packageManager.getPackageInfo( - selectedAppPackage.value.get(), + fun getSelectedPackageInfo(): PackageInfo? { + if (selectedAppPackage.value.isPresent) { + return app.packageManager.getPackageArchiveInfo( + selectedAppPackage.value.get().publicSourceDir, PackageManager.GET_META_DATA ) - else null + } + else {return null} + } fun checkSplitApk(): Boolean { if (getSelectedPackageInfo()!!.applicationInfo!!.metaData!!.getBoolean(