Compare commits

..

1 Commits

Author SHA1 Message Date
419fe3bac1 feat: Sort bundles by patch count 2025-05-05 01:29:06 +03:00
11 changed files with 45 additions and 80 deletions

View File

@ -27,7 +27,7 @@ android {
buildTypes { buildTypes {
debug { debug {
applicationIdSuffix = ".debug" applicationIdSuffix = ".debug"
resValue("string", "app_name", "ReVanced Manager (Debug)") resValue("string", "app_name", "ReVanced Manager (dev)")
isPseudoLocalesEnabled = true isPseudoLocalesEnabled = true
buildConfigField("long", "BUILD_ID", "${Random.nextLong()}L") buildConfigField("long", "BUILD_ID", "${Random.nextLong()}L")
@ -40,21 +40,12 @@ android {
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
} }
val keystoreFile = file("keystore.jks") if (project.hasProperty("signAsDebug")) {
applicationIdSuffix = ".debug"
if (project.hasProperty("signAsDebug") || !keystoreFile.exists()) { resValue("string", "app_name", "ReVanced Manager Debug")
applicationIdSuffix = ".debug_signed"
resValue("string", "app_name", "ReVanced Manager (Debug signed)")
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
isPseudoLocalesEnabled = true isPseudoLocalesEnabled = true
} else {
signingConfig = signingConfigs.create("release") {
storeFile = keystoreFile
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = System.getenv("KEYSTORE_ENTRY_ALIAS")
keyPassword = System.getenv("KEYSTORE_ENTRY_PASSWORD")
}
} }
buildConfigField("long", "BUILD_ID", "0L") buildConfigField("long", "BUILD_ID", "0L")
@ -72,17 +63,15 @@ android {
} }
packaging { packaging {
resources.excludes.addAll( resources.excludes.addAll(listOf(
listOf( "/prebuilt/**",
"/prebuilt/**", "META-INF/DEPENDENCIES",
"META-INF/DEPENDENCIES", "META-INF/**.version",
"META-INF/**.version", "DebugProbesKt.bin",
"DebugProbesKt.bin", "kotlin-tooling-metadata.json",
"kotlin-tooling-metadata.json", "org/bouncycastle/pqc/**.properties",
"org/bouncycastle/pqc/**.properties", "org/bouncycastle/x509/**.properties",
"org/bouncycastle/x509/**.properties", ))
)
)
jniLibs { jniLibs {
useLegacyPackaging = true useLegacyPackaging = true
} }

View File

@ -277,10 +277,6 @@ private fun ReVancedManager(vm: MainViewModel) {
AdvancedSettingsScreen(onBackClick = navController::popBackStack) AdvancedSettingsScreen(onBackClick = navController::popBackStack)
} }
composable<Settings.DeveloperOptions> {
DeveloperOptionsScreen(onBackClick = navController::popBackStack)
}
composable<Settings.Updates> { composable<Settings.Updates> {
UpdatesSettingsScreen( UpdatesSettingsScreen(
onBackClick = navController::popBackStack, onBackClick = navController::popBackStack,
@ -316,6 +312,9 @@ private fun ReVancedManager(vm: MainViewModel) {
LicensesScreen(onBackClick = navController::popBackStack) LicensesScreen(onBackClick = navController::popBackStack)
} }
composable<Settings.DeveloperOptions> {
DeveloperOptionsScreen(onBackClick = navController::popBackStack)
}
} }
} }
} }

View File

@ -111,7 +111,6 @@ class ProcessRuntime(private val context: Context) : Runtime(context) {
} }
val patching = CompletableDeferred<Unit>() val patching = CompletableDeferred<Unit>()
val scope = this
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
val binder = awaitBinderConnection() val binder = awaitBinderConnection()
@ -125,7 +124,7 @@ class ProcessRuntime(private val context: Context) : Runtime(context) {
override fun log(level: String, msg: String) = logger.log(enumValueOf(level), msg) override fun log(level: String, msg: String) = logger.log(enumValueOf(level), msg)
override fun patchSucceeded() { override fun patchSucceeded() {
scope.launch { onPatchCompleted() } launch { onPatchCompleted() }
} }
override fun progress(name: String?, state: String?, msg: String?) = override fun progress(name: String?, state: String?, msg: String?) =
@ -180,7 +179,7 @@ class ProcessRuntime(private val context: Context) : Runtime(context) {
} }
/** /**
* An [Exception] occurred in the remote process while patching. * An [Exception] occured in the remote process while patching.
* *
* @param originalStackTrace The stack trace of the original [Exception]. * @param originalStackTrace The stack trace of the original [Exception].
*/ */

View File

@ -1,10 +1,8 @@
package app.revanced.manager.patcher.runtime.process package app.revanced.manager.patcher.runtime.process
import android.annotation.SuppressLint
import android.app.ActivityThread import android.app.ActivityThread
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Looper import android.os.Looper
import app.revanced.manager.BuildConfig import app.revanced.manager.BuildConfig
@ -97,10 +95,6 @@ class PatcherProcess(private val context: Context) : IPatcherProcess.Stub() {
} }
companion object { companion object {
private val longArrayClass = LongArray::class.java
private val emptyLongArray = LongArray(0)
@SuppressLint("PrivateApi")
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
Looper.prepare() Looper.prepare()
@ -111,15 +105,6 @@ class PatcherProcess(private val context: Context) : IPatcherProcess.Stub() {
val systemContext = ActivityThread.systemMain().systemContext as Context val systemContext = ActivityThread.systemMain().systemContext as Context
val appContext = systemContext.createPackageContext(managerPackageName, 0) val appContext = systemContext.createPackageContext(managerPackageName, 0)
// Avoid annoying logs. See https://github.com/robolectric/robolectric/blob/ad0484c6b32c7d11176c711abeb3cb4a900f9258/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java#L376-L388
Class.forName("android.app.AppCompatCallbacks").apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
getDeclaredMethod("install", longArrayClass, longArrayClass).also { it.isAccessible = true }(null, emptyLongArray, emptyLongArray)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getDeclaredMethod("install", longArrayClass).also { it.isAccessible = true }(null, emptyLongArray)
}
}
val ipcInterface = PatcherProcess(appContext) val ipcInterface = PatcherProcess(appContext)
appContext.sendBroadcast(Intent().apply { appContext.sendBroadcast(Intent().apply {

View File

@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -20,10 +19,8 @@ fun BundleListScreen(
selectedSources: SnapshotStateList<PatchBundleSource>, selectedSources: SnapshotStateList<PatchBundleSource>,
bundlesSelectable: Boolean, bundlesSelectable: Boolean,
) { ) {
val sortedSources = remember(sources) { val sortedSources = sources.sortedBy {
sources.sortedByDescending { source -> it.state.value.patchBundleOrNull()?.patches?.size
source.state.value.patchBundleOrNull()?.patches?.size ?: 0
}
} }
LazyColumnWithScrollbar( LazyColumnWithScrollbar(

View File

@ -41,11 +41,6 @@ private val settingsSections = listOf(
R.string.advanced_description, R.string.advanced_description,
Icons.Outlined.Tune Icons.Outlined.Tune
) to Settings.Advanced, ) to Settings.Advanced,
Triple(
R.string.developer_options,
R.string.developer_options_description,
Icons.Outlined.Code
) to Settings.DeveloperOptions,
Triple( Triple(
R.string.about, R.string.about,
R.string.app_name, R.string.app_name,

View File

@ -126,6 +126,11 @@ fun AboutSettingsScreen(
navigate(Settings.Contributors) navigate(Settings.Contributors)
} }
), ),
Triple(
stringResource(R.string.developer_options),
stringResource(R.string.developer_options_description),
third = { navigate(Settings.DeveloperOptions) }
),
Triple( Triple(
stringResource(R.string.opensource_licenses), stringResource(R.string.opensource_licenses),
stringResource(R.string.opensource_licenses_description), stringResource(R.string.opensource_licenses_description),

View File

@ -112,6 +112,20 @@ fun AdvancedSettingsScreen(
} }
) )
GroupHeader(stringResource(R.string.patcher))
BooleanItem(
preference = vm.prefs.useProcessRuntime,
coroutineScope = vm.viewModelScope,
headline = R.string.process_runtime,
description = R.string.process_runtime_description,
)
IntegerItem(
preference = vm.prefs.patcherProcessMemoryLimit,
coroutineScope = vm.viewModelScope,
headline = R.string.process_runtime_memory_limit,
description = R.string.process_runtime_memory_limit_description,
)
GroupHeader(stringResource(R.string.safeguards)) GroupHeader(stringResource(R.string.safeguards))
SafeguardBooleanItem( SafeguardBooleanItem(
preference = vm.prefs.disablePatchVersionCompatCheck, preference = vm.prefs.disablePatchVersionCompatCheck,
@ -142,20 +156,6 @@ fun AdvancedSettingsScreen(
confirmationText = R.string.patch_selection_safeguard_confirmation confirmationText = R.string.patch_selection_safeguard_confirmation
) )
GroupHeader(stringResource(R.string.patcher))
BooleanItem(
preference = vm.prefs.useProcessRuntime,
coroutineScope = vm.viewModelScope,
headline = R.string.process_runtime,
description = R.string.process_runtime_description,
)
IntegerItem(
preference = vm.prefs.patcherProcessMemoryLimit,
coroutineScope = vm.viewModelScope,
headline = R.string.process_runtime_memory_limit,
description = R.string.process_runtime_memory_limit_description,
)
GroupHeader(stringResource(R.string.debugging)) GroupHeader(stringResource(R.string.debugging))
val exportDebugLogsLauncher = val exportDebugLogsLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {

View File

@ -4,7 +4,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.ui.theme.Theme import app.revanced.manager.ui.theme.Theme
import app.revanced.manager.util.resetListItemColorsCached
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class GeneralSettingsViewModel( class GeneralSettingsViewModel(
@ -12,6 +11,5 @@ class GeneralSettingsViewModel(
) : ViewModel() { ) : ViewModel() {
fun setTheme(theme: Theme) = viewModelScope.launch { fun setTheme(theme: Theme) = viewModelScope.launch {
prefs.theme.update(theme) prefs.theme.update(theme)
resetListItemColorsCached()
} }
} }

View File

@ -180,10 +180,6 @@ fun LocalDateTime.relativeTime(context: Context): String {
private var transparentListItemColorsCached: ListItemColors? = null private var transparentListItemColorsCached: ListItemColors? = null
fun resetListItemColorsCached() {
transparentListItemColorsCached = null
}
/** /**
* The default ListItem colors, but with [ListItemColors.containerColor] set to [Color.Transparent]. * The default ListItem colors, but with [ListItemColors.containerColor] set to [Color.Transparent].
*/ */

View File

@ -1,16 +1,19 @@
pluginManagement { pluginManagement {
repositories { repositories {
mavenCentral()
google()
gradlePluginPortal() gradlePluginPortal()
google()
mavenCentral()
maven("https://jitpack.io")
mavenLocal()
} }
} }
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {
mavenCentral()
google() google()
mavenCentral()
maven("https://jitpack.io") maven("https://jitpack.io")
mavenLocal()
maven { maven {
// A repository must be specified for some reason. "registry" is a dummy. // A repository must be specified for some reason. "registry" is a dummy.
url = uri("https://maven.pkg.github.com/revanced/registry") url = uri("https://maven.pkg.github.com/revanced/registry")
@ -21,6 +24,5 @@ dependencyResolutionManagement {
} }
} }
} }
rootProject.name = "ReVanced Manager" rootProject.name = "ReVanced Manager"
include(":app") include(":app")