Skip to content

Commit

Permalink
fix: Modernize some APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Apr 28, 2024
1 parent cf59950 commit 85c83e0
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 139 deletions.
52 changes: 34 additions & 18 deletions api/revanced-patcher.api
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,15 @@ public final class app/revanced/patcher/extensions/InstructionExtensions {
public final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V
}

public abstract interface annotation class app/revanced/patcher/fingerprint/FuzzyPatternScanMethod : java/lang/annotation/Annotation {
public abstract fun threshold ()I
}

public final class app/revanced/patcher/fingerprint/MethodFingerprint {
public fun <init> ()V
public final fun getFuzzyPatternScanMethod ()Lapp/revanced/patcher/fingerprint/FuzzyPatternScanMethod;
public final fun getResult ()Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public final fun resolve (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun resolve (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
}

public final class app/revanced/patcher/fingerprint/MethodFingerprintBuilder {
public fun <init> ()V
public final fun accessFlags (I)V
public final fun accessFlags (Lcom/android/tools/smali/dexlib2/AccessFlags;)V
public final fun custom (Lkotlin/jvm/functions/Function2;)V
Expand All @@ -126,8 +122,10 @@ public final class app/revanced/patcher/fingerprint/MethodFingerprintBuilder {
}

public final class app/revanced/patcher/fingerprint/MethodFingerprintKt {
public static final fun methodFingerprint (Lapp/revanced/patcher/patch/BytecodePatchBuilder;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static final fun methodFingerprint (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static final fun methodFingerprint (ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static final fun methodFingerprint (Lapp/revanced/patcher/patch/BytecodePatchBuilder;ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static synthetic fun methodFingerprint$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static synthetic fun methodFingerprint$default (Lapp/revanced/patcher/patch/BytecodePatchBuilder;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/MethodFingerprint;
public static final fun resolve (Ljava/lang/Iterable;Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/Iterable;)V
}

Expand Down Expand Up @@ -173,13 +171,13 @@ public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revance
}

public final class app/revanced/patcher/patch/BytecodePatchContext : app/revanced/patcher/patch/PatchContext {
public final fun findClass (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun findClass (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun classBy (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun classByType (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Ljava/util/Set;
public final fun getClasses ()Lapp/revanced/patcher/util/ProxyClassList;
public final fun navigate (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/MethodNavigator;
public final fun proxy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun toMethodWalker (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/method/MethodWalker;
}

public final class app/revanced/patcher/patch/Option {
Expand Down Expand Up @@ -486,33 +484,51 @@ public final class app/revanced/patcher/util/Document : java/io/Closeable, org/w
public fun setXmlVersion (Ljava/lang/String;)V
}

public final class app/revanced/patcher/util/ProxyClassList : java/util/Set, kotlin/jvm/internal/markers/KMutableSet {
public final fun add (Lapp/revanced/patcher/util/proxy/ClassProxy;)Z
public final class app/revanced/patcher/util/MethodNavigator {
public final fun at ([I)Lapp/revanced/patcher/util/MethodNavigator;
public final fun getReference ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;
public final fun immutable ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun mutable ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public final fun setReference (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)V
}

public final class app/revanced/patcher/util/ProxyClassList : java/util/List, kotlin/jvm/internal/markers/KMutableList {
public fun add (ILcom/android/tools/smali/dexlib2/iface/ClassDef;)V
public synthetic fun add (ILjava/lang/Object;)V
public fun add (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public synthetic fun add (Ljava/lang/Object;)Z
public fun addAll (ILjava/util/Collection;)Z
public fun addAll (Ljava/util/Collection;)Z
public fun clear ()V
public fun contains (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun contains (Ljava/lang/Object;)Z
public fun containsAll (Ljava/util/Collection;)Z
public fun get (I)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public synthetic fun get (I)Ljava/lang/Object;
public fun getSize ()I
public fun indexOf (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)I
public final fun indexOf (Ljava/lang/Object;)I
public fun isEmpty ()Z
public fun iterator ()Ljava/util/Iterator;
public fun lastIndexOf (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)I
public final fun lastIndexOf (Ljava/lang/Object;)I
public fun listIterator ()Ljava/util/ListIterator;
public fun listIterator (I)Ljava/util/ListIterator;
public final fun remove (I)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public synthetic fun remove (I)Ljava/lang/Object;
public fun remove (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun remove (Ljava/lang/Object;)Z
public fun removeAll (Ljava/util/Collection;)Z
public fun removeAt (I)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public fun retainAll (Ljava/util/Collection;)Z
public fun set (ILcom/android/tools/smali/dexlib2/iface/ClassDef;)Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public synthetic fun set (ILjava/lang/Object;)Ljava/lang/Object;
public final fun size ()I
public fun subList (II)Ljava/util/List;
public fun toArray ()[Ljava/lang/Object;
public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object;
}

public final class app/revanced/patcher/util/method/MethodWalker {
public final fun getMethod ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun nextMethod (IZ)Lapp/revanced/patcher/util/method/MethodWalker;
public static synthetic fun nextMethod$default (Lapp/revanced/patcher/util/method/MethodWalker;IZILjava/lang/Object;)Lapp/revanced/patcher/util/method/MethodWalker;
}

public final class app/revanced/patcher/util/proxy/ClassProxy {
public final fun getImmutableClass ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun getMutableClass ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
Expand Down
16 changes: 8 additions & 8 deletions src/main/kotlin/app/revanced/patcher/Patcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Patcher(
val context = PatcherContext(config)

init {
context.resourceContext.decodeResources(ResourcePatchContext.ResourceMode.NONE)
context.resourcePatchContext.decodeResources(ResourcePatchContext.ResourceMode.NONE)
}

/**
Expand Down Expand Up @@ -85,7 +85,7 @@ class Patcher(
// Check, if integrations need to be merged.
for (patch in patches)
if (patch.anyRecursively { it.requiresIntegrations }) {
context.bytecodeContext.integrations.merge = true
context.bytecodePatchContext.integrations.merge = true
break
}
}
Expand All @@ -94,7 +94,7 @@ class Patcher(

// region Add integrations

context.bytecodeContext.integrations.addAll(integrations)
context.bytecodePatchContext.integrations.addAll(integrations)

// endregion
}
Expand Down Expand Up @@ -140,13 +140,13 @@ class Patcher(
}.also { executedPatches[this] = it }
}

if (context.bytecodeContext.integrations.merge) context.bytecodeContext.integrations.flush()
if (context.bytecodePatchContext.integrations.merge) context.bytecodePatchContext.integrations.flush()

LookupMap.initializeLookupMaps(context.bytecodeContext)
LookupMap.initializeLookupMaps(context.bytecodePatchContext)

// Prevent from decoding the app manifest twice if it is not needed.
if (config.resourceMode != ResourcePatchContext.ResourceMode.NONE) {
context.resourceContext.decodeResources(config.resourceMode)
context.resourcePatchContext.decodeResources(config.resourceMode)
}

logger.info("Executing patches")
Expand Down Expand Up @@ -212,8 +212,8 @@ class Patcher(
@OptIn(InternalApi::class)
override fun get() =
PatcherResult(
context.bytecodeContext.get(),
context.resourceContext.get(),
context.bytecodePatchContext.get(),
context.resourcePatchContext.get(),
)
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/kotlin/app/revanced/patcher/PatcherContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ class PatcherContext internal constructor(config: PatcherConfig) {
internal val allPatches = mutableSetOf<Patch<*>>()

/**
* A context for the patcher containing the current state of the resources.
* A context for patches containing the current state of the resources.
*/
internal val resourceContext = ResourcePatchContext(packageMetadata, config)
internal val resourcePatchContext = ResourcePatchContext(packageMetadata, config)

/**
* A context for the patcher containing the current state of the bytecode.
* A context for patches containing the current state of the bytecode.
*/
internal val bytecodeContext = BytecodePatchContext(config)
internal val bytecodePatchContext = BytecodePatchContext(config)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("unused", "MemberVisibilityCanBePrivate")

package app.revanced.patcher.fingerprint

import app.revanced.patcher.fingerprint.LookupMap.Maps.appendParameters
Expand Down Expand Up @@ -326,7 +328,6 @@ fun Iterable<MethodFingerprint>.resolve(
* @param context The [BytecodePatchContext] this [MethodFingerprintResult] is attached to, to create proxies.
*/

@Suppress("MemberVisibilityCanBePrivate")
class MethodFingerprintResult(
val method: Method,
val classDef: ClassDef,
Expand All @@ -339,8 +340,11 @@ class MethodFingerprintResult(
* Please note, this method allocates a [ClassProxy].
* Use [classDef] where possible.
*/
@Suppress("MemberVisibilityCanBePrivate")
val mutableClass by lazy { context.proxy(classDef).mutableClass }
val mutableClass by lazy {
with(context) {
classDef.proxy().mutableClass
}
}

/**
* Returns a mutable clone of [method]
Expand Down
40 changes: 16 additions & 24 deletions src/main/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import app.revanced.patcher.PatcherConfig
import app.revanced.patcher.PatcherContext
import app.revanced.patcher.PatcherResult
import app.revanced.patcher.util.ClassMerger.merge
import app.revanced.patcher.util.MethodNavigator
import app.revanced.patcher.util.ProxyClassList
import app.revanced.patcher.util.method.MethodWalker
import app.revanced.patcher.util.proxy.ClassProxy
import com.android.tools.smali.dexlib2.Opcodes
import com.android.tools.smali.dexlib2.iface.ClassDef
Expand Down Expand Up @@ -46,7 +46,7 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
BasicDexFileNamer(),
null,
null,
).also { opcodes = it.opcodes }.classes.toMutableSet(),
).also { opcodes = it.opcodes }.classes.toMutableList(),
)
}

Expand All @@ -56,44 +56,36 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
internal val integrations = Integrations()

/**
* Find a class by a given class name.
* Find a class by its type using a contains check.
*
* @param className The name of the class.
* @return A proxy for the first class that matches the class name.
* @param type The type of the class.
* @return A proxy for the first class that matches the type.
*/
fun findClass(className: String) = findClass { it.type.contains(className) }
fun classByType(type: String) = classBy { type in it.type }

/**
* Find a class by a given predicate.
* Find a class with a predicate.
*
* @param predicate A predicate to match the class.
* @return A proxy for the first class that matches the predicate.
*/
fun findClass(predicate: (ClassDef) -> Boolean) =
// if we already proxied the class matching the predicate...
classes.proxies.firstOrNull { predicate(it.immutableClass) }
?: // else resolve the class to a proxy and return it, if the predicate is matching a class
classes.find(predicate)?.let { proxy(it) }
fun classBy(predicate: (ClassDef) -> Boolean) =
classes.proxyPool.find { predicate(it.immutableClass) } ?: classes.find(predicate)?.proxy()

/**
* Proxy a class.
* This will allow the class to be modified.
* Proxy the class to allow mutation.
*
* @param classDef The class to proxy.
* @return A proxy for the class.
*/
fun proxy(classDef: ClassDef) =
this.classes.proxies.find { it.immutableClass.type == classDef.type } ?: let {
ClassProxy(classDef).also { this.classes.add(it) }
}
fun ClassDef.proxy() = this@BytecodePatchContext.classes.proxyPool.find { it.immutableClass.type == type }
?: ClassProxy(this).also { this@BytecodePatchContext.classes.proxyPool.add(it) }

/**
* Create a [MethodWalker] instance for the current [BytecodePatchContext].
* Navigate a method.
*
* @param startMethod The method to start at.
* @return A [MethodWalker] instance.
* @return A [MethodNavigator] for the method.
*/
fun toMethodWalker(startMethod: Method) = MethodWalker(this, startMethod)
fun Method.navigate() = MethodNavigator(this@BytecodePatchContext, this)

/**
* Compile bytecode from the [BytecodePatchContext].
Expand All @@ -116,7 +108,7 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
BasicDexFileNamer(),
object : DexFile {
override fun getClasses() =
this@BytecodePatchContext.classes.also(ProxyClassList::replaceClasses)
this@BytecodePatchContext.classes.also(ProxyClassList::replaceClasses).toSet()

override fun getOpcodes() = this@BytecodePatchContext.opcodes
},
Expand Down
14 changes: 7 additions & 7 deletions src/main/kotlin/app/revanced/patcher/patch/Patch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ class BytecodePatch internal constructor(
finalizeBlock,
) {
override fun execute(context: PatcherContext) {
fingerprints.resolveUsingLookupMap(context.bytecodeContext)
fingerprints.resolveUsingLookupMap(context.bytecodePatchContext)

execute(context.bytecodeContext)
execute(context.bytecodePatchContext)
}

override fun finalize(context: PatcherContext) = finalize(context.bytecodeContext)
override fun finalize(context: PatcherContext) = finalize(context.bytecodePatchContext)
}

/**
Expand Down Expand Up @@ -177,8 +177,8 @@ class RawResourcePatch internal constructor(
executeBlock,
finalizeBlock,
) {
override fun execute(context: PatcherContext) = execute(context.resourceContext)
override fun finalize(context: PatcherContext) = finalize(context.resourceContext)
override fun execute(context: PatcherContext) = execute(context.resourcePatchContext)
override fun finalize(context: PatcherContext) = finalize(context.resourcePatchContext)
}

/**
Expand Down Expand Up @@ -220,8 +220,8 @@ class ResourcePatch internal constructor(
executeBlock,
finalizeBlock,
) {
override fun execute(context: PatcherContext) = execute(context.resourceContext)
override fun finalize(context: PatcherContext) = finalize(context.resourceContext)
override fun execute(context: PatcherContext) = execute(context.resourcePatchContext)
override fun finalize(context: PatcherContext) = finalize(context.resourcePatchContext)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class ResourcePatchContext internal constructor(
// Excluded because present in resources.other.
// TODO: We are reusing config.apkFiles as a temporarily directory for extracting resources.
// This is not ideal as it could conflict with files such as the ones that we filter here.
// The problem is that ResourceContext#get returns a File relative to config.apkFiles,
// The problem is that ResourcePatchContext#get returns a File relative to config.apkFiles,
// and we need to extract files to that directory.
// A solution would be to use config.apkFiles as the working directory for the patching process.
// Once all patches have been executed, we can move the decoded resources to a new directory.
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ internal object ClassMerger {
callback: MutableClass.() -> Unit,
) {
callback(targetClass)
this.findClass(targetClass.superclass ?: return)?.mutableClass?.let {
this.classByType(targetClass.superclass ?: return)?.mutableClass?.let {
traverseClassHierarchy(it, callback)
}
}
Expand Down
Loading

0 comments on commit 85c83e0

Please sign in to comment.