mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2026-01-11 13:56:16 +00:00
feat: Add callback for patch loading exceptions
This commit is contained in:
@@ -342,8 +342,12 @@ public final class app/revanced/patcher/patch/PatchKt {
|
|||||||
public static final fun bytecodePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun bytecodePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static synthetic fun bytecodePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
public static synthetic fun bytecodePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
public static final fun loadPatchesFromDex (Ljava/util/Set;Ljava/io/File;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
public static final fun loadPatchesFromDex (Ljava/util/Set;Ljava/io/File;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
||||||
|
public static final fun loadPatchesFromDex (Ljava/util/Set;Ljava/io/File;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
||||||
public static synthetic fun loadPatchesFromDex$default (Ljava/util/Set;Ljava/io/File;ILjava/lang/Object;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
public static synthetic fun loadPatchesFromDex$default (Ljava/util/Set;Ljava/io/File;ILjava/lang/Object;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
||||||
|
public static synthetic fun loadPatchesFromDex$default (Ljava/util/Set;Ljava/io/File;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/PatchLoader$Dex;
|
||||||
public static final fun loadPatchesFromJar (Ljava/util/Set;)Lapp/revanced/patcher/patch/PatchLoader$Jar;
|
public static final fun loadPatchesFromJar (Ljava/util/Set;)Lapp/revanced/patcher/patch/PatchLoader$Jar;
|
||||||
|
public static final fun loadPatchesFromJar (Ljava/util/Set;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/PatchLoader$Jar;
|
||||||
|
public static synthetic fun loadPatchesFromJar$default (Ljava/util/Set;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/PatchLoader$Jar;
|
||||||
public static final fun rawResourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/RawResourcePatch;
|
public static final fun rawResourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/RawResourcePatch;
|
||||||
public static synthetic fun rawResourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch;
|
public static synthetic fun rawResourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch;
|
||||||
public static final fun resourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch;
|
public static final fun resourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
@@ -352,7 +356,7 @@ public final class app/revanced/patcher/patch/PatchKt {
|
|||||||
|
|
||||||
public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker {
|
public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker {
|
||||||
public synthetic fun <init> (Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public synthetic fun <init> (Ljava/util/Set;Lkotlin/jvm/functions/Function1;Ljava/lang/ClassLoader;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/util/Set;Lkotlin/jvm/functions/Function1;Ljava/lang/ClassLoader;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun add (Lapp/revanced/patcher/patch/Patch;)Z
|
public fun add (Lapp/revanced/patcher/patch/Patch;)Z
|
||||||
public synthetic fun add (Ljava/lang/Object;)Z
|
public synthetic fun add (Ljava/lang/Object;)Z
|
||||||
public fun addAll (Ljava/util/Collection;)Z
|
public fun addAll (Ljava/util/Collection;)Z
|
||||||
@@ -373,12 +377,9 @@ public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, ko
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/PatchLoader$Dex : app/revanced/patcher/patch/PatchLoader {
|
public final class app/revanced/patcher/patch/PatchLoader$Dex : app/revanced/patcher/patch/PatchLoader {
|
||||||
public fun <init> (Ljava/util/Set;Ljava/io/File;)V
|
|
||||||
public synthetic fun <init> (Ljava/util/Set;Ljava/io/File;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/PatchLoader$Jar : app/revanced/patcher/patch/PatchLoader {
|
public final class app/revanced/patcher/patch/PatchLoader$Jar : app/revanced/patcher/patch/PatchLoader {
|
||||||
public fun <init> (Ljava/util/Set;)V
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/PatchResult {
|
public final class app/revanced/patcher/patch/PatchResult {
|
||||||
|
|||||||
@@ -87,8 +87,7 @@ sealed class Patch<C : PatchContext<*>>(
|
|||||||
finalizeBlock?.invoke(context)
|
finalizeBlock?.invoke(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = name ?:
|
override fun toString() = name ?: "Patch@${System.identityHashCode(this)}"
|
||||||
"Patch@${System.identityHashCode(this)}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Patch<*>.anyRecursively(
|
internal fun Patch<*>.anyRecursively(
|
||||||
@@ -529,11 +528,11 @@ fun resourcePatch(
|
|||||||
/**
|
/**
|
||||||
* An exception thrown when patching.
|
* An exception thrown when patching.
|
||||||
*
|
*
|
||||||
* @param errorMessage The exception message.
|
* @param message The exception message.
|
||||||
* @param cause The corresponding [Throwable].
|
* @param cause The cause of the exception.
|
||||||
*/
|
*/
|
||||||
class PatchException(errorMessage: String?, cause: Throwable?) : Exception(errorMessage, cause) {
|
class PatchException(message: String?, cause: Throwable?) : Exception(message, cause) {
|
||||||
constructor(errorMessage: String) : this(errorMessage, null)
|
constructor(message: String) : this(message, null)
|
||||||
constructor(cause: Throwable) : this(cause.message, cause)
|
constructor(cause: Throwable) : this(cause.message, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,6 +542,7 @@ class PatchException(errorMessage: String?, cause: Throwable?) : Exception(error
|
|||||||
* @param patch The [Patch] that was executed.
|
* @param patch The [Patch] that was executed.
|
||||||
* @param exception The [PatchException] thrown, if any.
|
* @param exception The [PatchException] thrown, if any.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("This class is not used anymore. Instead a callback is used")
|
||||||
class PatchResult internal constructor(val patch: Patch<*>, val exception: PatchException? = null)
|
class PatchResult internal constructor(val patch: Patch<*>, val exception: PatchException? = null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -553,35 +553,46 @@ class PatchResult internal constructor(val patch: Patch<*>, val exception: Patch
|
|||||||
*
|
*
|
||||||
* @param byPatchesFile The patches associated by the patches file they were loaded from.
|
* @param byPatchesFile The patches associated by the patches file they were loaded from.
|
||||||
*/
|
*/
|
||||||
sealed class PatchLoader private constructor(
|
sealed class PatchLoader(
|
||||||
val byPatchesFile: Map<File, Set<Patch<*>>>,
|
val byPatchesFile: Map<File, Set<Patch<*>>>,
|
||||||
) : Set<Patch<*>> by byPatchesFile.values.flatten().toSet() {
|
) : Set<Patch<*>> by byPatchesFile.values.flatten().toSet() {
|
||||||
/**
|
/**
|
||||||
* @param patchesFiles A set of JAR or DEX files to load the patches from.
|
* @param patchesFiles A set of JAR or DEX files to load the patches from.
|
||||||
* @param getBinaryClassNames A function that returns the binary names of all classes accessible by the class loader.
|
* @param getBinaryClassNames A function that returns the binary names of all classes accessible by the class loader.
|
||||||
* @param classLoader The [ClassLoader] to use for loading the classes.
|
* @param classLoader The [ClassLoader] to use for loading the classes.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*/
|
*/
|
||||||
private constructor(
|
constructor(
|
||||||
patchesFiles: Set<File>,
|
patchesFiles: Set<File>,
|
||||||
getBinaryClassNames: (patchesFile: File) -> List<String>,
|
getBinaryClassNames: (patchesFile: File) -> List<String>,
|
||||||
classLoader: ClassLoader,
|
classLoader: ClassLoader,
|
||||||
) : this(classLoader.loadPatches(patchesFiles.associateWith { getBinaryClassNames(it).toSet() }))
|
onLoadPatchesException: (message: String, cause: Throwable) -> Unit
|
||||||
|
) : this(
|
||||||
|
classLoader.loadPatches(
|
||||||
|
patchesFiles.associateWith { getBinaryClassNames(it).toSet() },
|
||||||
|
onLoadPatchesException
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [PatchLoader] for JAR files.
|
* A [PatchLoader] for JAR files.
|
||||||
*
|
*
|
||||||
* @param patchesFiles The JAR files to load the patches from.
|
* @param patchesFiles The JAR files to load the patches from.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*
|
*
|
||||||
* @constructor Create a new [PatchLoader] for JAR files.
|
* @constructor Create a new [PatchLoader] for JAR files.
|
||||||
*/
|
*/
|
||||||
class Jar(patchesFiles: Set<File>) :
|
class Jar internal constructor(
|
||||||
PatchLoader(
|
patchesFiles: Set<File>,
|
||||||
|
onLoadPatchesException: (message: String, cause: Throwable) -> Unit
|
||||||
|
) : PatchLoader(
|
||||||
patchesFiles,
|
patchesFiles,
|
||||||
{ file ->
|
{ file ->
|
||||||
JarFile(file).entries().toList().filter { it.name.endsWith(".class") }
|
JarFile(file).entries().toList().filter { it.name.endsWith(".class") }
|
||||||
.map { it.name.substringBeforeLast('.').replace('/', '.') }
|
.map { it.name.substringBeforeLast('.').replace('/', '.') }
|
||||||
},
|
},
|
||||||
URLClassLoader(patchesFiles.map { it.toURI().toURL() }.toTypedArray()),
|
URLClassLoader(patchesFiles.map { it.toURI().toURL() }.toTypedArray()),
|
||||||
|
onLoadPatchesException
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -590,11 +601,15 @@ sealed class PatchLoader private constructor(
|
|||||||
* @param patchesFiles The DEX files to load the patches from.
|
* @param patchesFiles The DEX files to load the patches from.
|
||||||
* @param optimizedDexDirectory The directory to store optimized DEX files in.
|
* @param optimizedDexDirectory The directory to store optimized DEX files in.
|
||||||
* This parameter is deprecated and has no effect since API level 26.
|
* This parameter is deprecated and has no effect since API level 26.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*
|
*
|
||||||
* @constructor Create a new [PatchLoader] for [Dex] files.
|
* @constructor Create a new [PatchLoader] for [Dex] files.
|
||||||
*/
|
*/
|
||||||
class Dex(patchesFiles: Set<File>, optimizedDexDirectory: File? = null) :
|
class Dex internal constructor(
|
||||||
PatchLoader(
|
patchesFiles: Set<File>,
|
||||||
|
optimizedDexDirectory: File? = null,
|
||||||
|
onLoadPatchesException: (message: String, cause: Throwable) -> Unit
|
||||||
|
) : PatchLoader(
|
||||||
patchesFiles,
|
patchesFiles,
|
||||||
{ patchBundle ->
|
{ patchBundle ->
|
||||||
MultiDexIO.readDexFile(true, patchBundle, BasicDexFileNamer(), null, null).classes
|
MultiDexIO.readDexFile(true, patchBundle, BasicDexFileNamer(), null, null).classes
|
||||||
@@ -608,6 +623,7 @@ sealed class PatchLoader private constructor(
|
|||||||
null,
|
null,
|
||||||
this::class.java.classLoader,
|
this::class.java.classLoader,
|
||||||
),
|
),
|
||||||
|
onLoadPatchesException
|
||||||
)
|
)
|
||||||
|
|
||||||
// Companion object required for unit tests.
|
// Companion object required for unit tests.
|
||||||
@@ -640,13 +656,18 @@ sealed class PatchLoader private constructor(
|
|||||||
*
|
*
|
||||||
* @param binaryClassNamesByPatchesFile The binary class name of the classes to load the patches from
|
* @param binaryClassNamesByPatchesFile The binary class name of the classes to load the patches from
|
||||||
* associated by the patches file.
|
* associated by the patches file.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*
|
*
|
||||||
* @return The loaded patches associated by the patches file.
|
* @return The loaded patches associated by the patches file.
|
||||||
*/
|
*/
|
||||||
private fun ClassLoader.loadPatches(binaryClassNamesByPatchesFile: Map<File, Set<String>>) =
|
private fun ClassLoader.loadPatches(
|
||||||
binaryClassNamesByPatchesFile.mapValues { (_, binaryClassNames) ->
|
binaryClassNamesByPatchesFile: Map<File, Set<String>>,
|
||||||
binaryClassNames.asSequence().map {
|
onLoadPatchesException: (message: String, cause: Throwable) -> Unit
|
||||||
loadClass(it)
|
) = binaryClassNamesByPatchesFile.mapValues { (_, binaryClassNames) ->
|
||||||
|
binaryClassNames.asSequence().mapNotNull {
|
||||||
|
runCatching { loadClass(it) }.onFailure { exception ->
|
||||||
|
onLoadPatchesException("Failed to load patch class $it", exception)
|
||||||
|
}.getOrNull()
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
it.patchFields + it.patchMethods
|
it.patchFields + it.patchMethods
|
||||||
}.filter {
|
}.filter {
|
||||||
@@ -668,11 +689,22 @@ sealed class PatchLoader private constructor(
|
|||||||
* Patches with no name are not loaded.
|
* Patches with no name are not loaded.
|
||||||
*
|
*
|
||||||
* @param patchesFiles The JAR files to load the patches from.
|
* @param patchesFiles The JAR files to load the patches from.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*
|
*
|
||||||
* @return The loaded patches.
|
* @return The loaded patches.
|
||||||
*/
|
*/
|
||||||
fun loadPatchesFromJar(patchesFiles: Set<File>) =
|
fun loadPatchesFromJar(
|
||||||
PatchLoader.Jar(patchesFiles)
|
patchesFiles: Set<File>,
|
||||||
|
onLoadPatchesException: ((message: String, cause: Throwable) -> Unit)? = null
|
||||||
|
) = PatchLoader.Jar(patchesFiles, onLoadPatchesException ?: { message, cause -> })
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Use the function with the onLoadPatchesException overload",
|
||||||
|
replaceWith = ReplaceWith("loadPatchesFromJar(patchesFiles, null)")
|
||||||
|
)
|
||||||
|
fun loadPatchesFromJar(
|
||||||
|
patchesFiles: Set<File>
|
||||||
|
) = loadPatchesFromJar(patchesFiles, null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads patches from DEX files declared as public static fields
|
* Loads patches from DEX files declared as public static fields
|
||||||
@@ -680,8 +712,21 @@ fun loadPatchesFromJar(patchesFiles: Set<File>) =
|
|||||||
* Patches with no name are not loaded.
|
* Patches with no name are not loaded.
|
||||||
*
|
*
|
||||||
* @param patchesFiles The DEX files to load the patches from.
|
* @param patchesFiles The DEX files to load the patches from.
|
||||||
|
* @param onLoadPatchesException The callback for patches that could not be loaded.
|
||||||
*
|
*
|
||||||
* @return The loaded patches.
|
* @return The loaded patches.
|
||||||
*/
|
*/
|
||||||
fun loadPatchesFromDex(patchesFiles: Set<File>, optimizedDexDirectory: File? = null) =
|
fun loadPatchesFromDex(
|
||||||
PatchLoader.Dex(patchesFiles, optimizedDexDirectory)
|
patchesFiles: Set<File>,
|
||||||
|
optimizedDexDirectory: File? = null,
|
||||||
|
onLoadPatchesException: ((message: String, cause: Throwable) -> Unit)? = null
|
||||||
|
) = PatchLoader.Dex(patchesFiles, optimizedDexDirectory, onLoadPatchesException ?: { message, cause -> })
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Use the function with the onLoadPatchesException overload",
|
||||||
|
replaceWith = ReplaceWith("loadPatchesFromJar(patchesFiles, optimizedDexDirectory, null)")
|
||||||
|
)
|
||||||
|
fun loadPatchesFromDex(
|
||||||
|
patchesFiles: Set<File>,
|
||||||
|
optimizedDexDirectory: File? = null,
|
||||||
|
) = loadPatchesFromDex(patchesFiles, optimizedDexDirectory, null)
|
||||||
|
|||||||
Reference in New Issue
Block a user