From ba56a6a2eef503c0d6cdd846ddce2e1474d8ed1a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 24 Aug 2023 04:43:16 +0200 Subject: [PATCH] feat: properly make use of logging facade This deprecates the primary constructor of `PatcherOptions` with the `logger` parameter --- .../kotlin/app/revanced/patcher/Patcher.kt | 5 ++- .../app/revanced/patcher/PatcherOptions.kt | 34 +++++++++++--- .../revanced/patcher/data/BytecodeContext.kt | 21 +++++---- .../revanced/patcher/data/ResourceContext.kt | 9 ++-- .../app/revanced/patcher/logging/Logger.kt | 1 + .../patcher/logging/impl/NopLogger.kt | 1 + .../app/revanced/patcher/util/ClassMerger.kt | 44 ++++++++----------- 7 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/src/main/kotlin/app/revanced/patcher/Patcher.kt index c2e60af..2959f6b 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/patcher/Patcher.kt @@ -15,6 +15,7 @@ import java.io.File import java.util.function.Supplier import java.util.logging.Level import java.util.logging.LogManager +import java.util.logging.Logger /** * ReVanced Patcher. @@ -24,6 +25,8 @@ import java.util.logging.LogManager class Patcher( private val options: PatcherOptions ) : PatchExecutorFunction, PatchesConsumer, IntegrationsConsumer, Supplier, Closeable { + private val logger = Logger.getLogger(Patcher::class.java.name) + /** * The context of ReVanced [Patcher]. * This holds the current state of the patcher. @@ -159,7 +162,7 @@ class Patcher( if (options.resourceDecodingMode == ResourceContext.ResourceDecodingMode.FULL) context.resourceContext.decodeResources(ResourceContext.ResourceDecodingMode.FULL) - options.logger.info("Executing patches") + logger.info("Executing patches") val executedPatches = LinkedHashMap() // Key is name. diff --git a/src/main/kotlin/app/revanced/patcher/PatcherOptions.kt b/src/main/kotlin/app/revanced/patcher/PatcherOptions.kt index aa4d61d..1dfbdaa 100644 --- a/src/main/kotlin/app/revanced/patcher/PatcherOptions.kt +++ b/src/main/kotlin/app/revanced/patcher/PatcherOptions.kt @@ -1,10 +1,10 @@ package app.revanced.patcher import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.logging.Logger import app.revanced.patcher.logging.impl.NopLogger import brut.androlib.Config import java.io.File +import java.util.logging.Logger /** * Options for ReVanced [Patcher]. @@ -12,15 +12,19 @@ import java.io.File * @param resourceCachePath The path to the directory to use for caching resources. * @param aaptBinaryPath The path to a custom aapt binary. * @param frameworkFileDirectory The path to the directory to cache the framework file in. - * @param logger A [Logger]. + * @param unusedLogger The logger to use for logging. */ -data class PatcherOptions( +data class PatcherOptions +@Deprecated("Use the constructor without the logger parameter instead") +constructor( internal val inputFile: File, internal val resourceCachePath: File = File("revanced-resource-cache"), internal val aaptBinaryPath: String? = null, internal val frameworkFileDirectory: String? = null, - internal val logger: Logger = NopLogger + internal val unusedLogger: app.revanced.patcher.logging.Logger = NopLogger ) { + private val logger = Logger.getLogger(PatcherOptions::class.java.name) + /** * The mode to use for resource decoding. * @see ResourceContext.ResourceDecodingMode @@ -36,12 +40,32 @@ data class PatcherOptions( frameworkDirectory = frameworkFileDirectory } + /** + * Options for ReVanced [Patcher]. + * @param inputFile The input file to patch. + * @param resourceCachePath The path to the directory to use for caching resources. + * @param aaptBinaryPath The path to a custom aapt binary. + * @param frameworkFileDirectory The path to the directory to cache the framework file in. + */ + constructor( + inputFile: File, + resourceCachePath: File = File("revanced-resource-cache"), + aaptBinaryPath: String? = null, + frameworkFileDirectory: String? = null, + ) : this( + inputFile, + resourceCachePath, + aaptBinaryPath, + frameworkFileDirectory, + NopLogger + ) + fun recreateResourceCacheDirectory() = resourceCachePath.also { if (it.exists()) { logger.info("Deleting existing resource cache directory") if (!it.deleteRecursively()) - logger.error("Failed to delete existing resource cache directory") + logger.severe("Failed to delete existing resource cache directory") } it.mkdirs() diff --git a/src/main/kotlin/app/revanced/patcher/data/BytecodeContext.kt b/src/main/kotlin/app/revanced/patcher/data/BytecodeContext.kt index da2a539..eb44f79 100644 --- a/src/main/kotlin/app/revanced/patcher/data/BytecodeContext.kt +++ b/src/main/kotlin/app/revanced/patcher/data/BytecodeContext.kt @@ -1,8 +1,10 @@ package app.revanced.patcher.data +import app.revanced.patcher.PatcherContext import app.revanced.patcher.PatcherOptions import app.revanced.patcher.PatcherResult -import app.revanced.patcher.logging.Logger +import app.revanced.patcher.patch.Patch +import app.revanced.patcher.patch.annotations.RequiresIntegrations import app.revanced.patcher.util.ClassMerger.merge import app.revanced.patcher.util.ProxyClassList import app.revanced.patcher.util.method.MethodWalker @@ -17,6 +19,7 @@ import lanchon.multidexlib2.DexIO import lanchon.multidexlib2.MultiDexIO import java.io.File import java.io.Flushable +import java.util.logging.Logger /** * A context for bytecode. @@ -26,6 +29,8 @@ import java.io.Flushable */ class BytecodeContext internal constructor(private val options: PatcherOptions) : Context> { + private val logger = Logger.getLogger(BytecodeContext::class.java.name) + /** * [Opcodes] of the supplied [PatcherOptions.inputFile]. */ @@ -45,7 +50,7 @@ class BytecodeContext internal constructor(private val options: PatcherOptions) /** * The [Integrations] of this [PatcherContext]. */ - internal val integrations = Integrations(options.logger) + internal val integrations = Integrations() /** * Find a class by a given class name. @@ -88,10 +93,8 @@ class BytecodeContext internal constructor(private val options: PatcherOptions) /** * The integrations of a [PatcherContext]. - * - * @param logger The logger to use. */ - internal inner class Integrations(private val logger: Logger) : MutableList by mutableListOf(), Flushable { + internal inner class Integrations : MutableList by mutableListOf(), Flushable { /** * Whether to merge integrations. * True when any supplied [Patch] is annotated with [RequiresIntegrations]. @@ -112,14 +115,14 @@ class BytecodeContext internal constructor(private val options: PatcherOptions) null ).classes.forEach classDef@{ classDef -> val existingClass = classes.find { it == classDef } ?: run { - logger.trace("Merging $classDef") + logger.fine("Merging $classDef") classes.add(classDef) return@classDef } - logger.trace("$classDef exists. Adding missing methods and fields.") + logger.fine("$classDef exists. Adding missing methods and fields.") - existingClass.merge(classDef, this@BytecodeContext, logger).let { mergedClass -> + existingClass.merge(classDef, this@BytecodeContext).let { mergedClass -> // If the class was merged, replace the original class with the merged class. if (mergedClass === existingClass) return@let classes.apply { remove(existingClass); add(mergedClass) } @@ -137,7 +140,7 @@ class BytecodeContext internal constructor(private val options: PatcherOptions) * @return The compiled bytecode. */ override fun get(): List { - options.logger.info("Compiling modified dex files") + logger.info("Compiling modified dex files") return mutableMapOf().apply { MultiDexIO.writeDexFile( diff --git a/src/main/kotlin/app/revanced/patcher/data/ResourceContext.kt b/src/main/kotlin/app/revanced/patcher/data/ResourceContext.kt index ad75eb1..8bfcb12 100644 --- a/src/main/kotlin/app/revanced/patcher/data/ResourceContext.kt +++ b/src/main/kotlin/app/revanced/patcher/data/ResourceContext.kt @@ -16,6 +16,7 @@ import java.io.File import java.io.InputStream import java.io.OutputStream import java.nio.file.Files +import java.util.logging.Logger /** * A context for resources. @@ -27,6 +28,8 @@ class ResourceContext internal constructor( private val context: PatcherContext, private val options: PatcherOptions ) : Context, Iterable { + private val logger = Logger.getLogger(ResourceContext::class.java.name) + val xmlEditor = XmlFileHolder() /** @@ -42,7 +45,7 @@ class ResourceContext internal constructor( ResourceDecodingMode.FULL -> { val outDir = options.recreateResourceCacheDirectory() - options.logger.info("Decoding resources") + logger.info("Decoding resources") resourcesDecoder.decodeResources(outDir) resourcesDecoder.decodeManifest(outDir) @@ -57,7 +60,7 @@ class ResourceContext internal constructor( } ResourceDecodingMode.MANIFEST_ONLY -> { - options.logger.info("Decoding app manifest") + logger.info("Decoding app manifest") // Decode manually instead of using resourceDecoder.decodeManifest // because it does not support decoding to an OutputStream. @@ -100,7 +103,7 @@ class ResourceContext internal constructor( var resourceFile: File? = null if (options.resourceDecodingMode == ResourceDecodingMode.FULL) { - options.logger.info("Compiling modified resources") + logger.info("Compiling modified resources") val cacheDirectory = ExtFile(options.resourceCachePath) val aaptFile = cacheDirectory.resolve("aapt_temp_file").also { diff --git a/src/main/kotlin/app/revanced/patcher/logging/Logger.kt b/src/main/kotlin/app/revanced/patcher/logging/Logger.kt index 63295e6..6b29454 100644 --- a/src/main/kotlin/app/revanced/patcher/logging/Logger.kt +++ b/src/main/kotlin/app/revanced/patcher/logging/Logger.kt @@ -1,5 +1,6 @@ package app.revanced.patcher.logging +@Deprecated("This will be removed in a future release") interface Logger { fun error(msg: String) {} fun warn(msg: String) {} diff --git a/src/main/kotlin/app/revanced/patcher/logging/impl/NopLogger.kt b/src/main/kotlin/app/revanced/patcher/logging/impl/NopLogger.kt index af88ab9..1185975 100644 --- a/src/main/kotlin/app/revanced/patcher/logging/impl/NopLogger.kt +++ b/src/main/kotlin/app/revanced/patcher/logging/impl/NopLogger.kt @@ -2,4 +2,5 @@ package app.revanced.patcher.logging.impl import app.revanced.patcher.logging.Logger +@Deprecated("This will be removed in a future release") object NopLogger : Logger \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt b/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt index b2326eb..37fb9df 100644 --- a/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt +++ b/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt @@ -2,7 +2,6 @@ package app.revanced.patcher.util import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.or -import app.revanced.patcher.logging.Logger import app.revanced.patcher.util.ClassMerger.Utils.asMutableClass import app.revanced.patcher.util.ClassMerger.Utils.filterAny import app.revanced.patcher.util.ClassMerger.Utils.filterNotAny @@ -18,6 +17,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.util.MethodUtil +import java.util.logging.Logger import kotlin.reflect.KFunction2 /** @@ -25,28 +25,28 @@ import kotlin.reflect.KFunction2 * Note: This will not consider method implementations or if the class is missing a superclass or interfaces. */ internal object ClassMerger { + private val logger = Logger.getLogger(ClassMerger::class.java.name) + /** * Merge a class with [otherClass]. * * @param otherClass The class to merge with * @param context The context to traverse the class hierarchy in. - * @param logger A logger. * @return The merged class or the original class if no merge was needed. */ - fun ClassDef.merge(otherClass: ClassDef, context: BytecodeContext, logger: Logger? = null) = this - //.fixFieldAccess(otherClass, logger) - //.fixMethodAccess(otherClass, logger) - .addMissingFields(otherClass, logger) - .addMissingMethods(otherClass, logger) - .publicize(otherClass, context, logger) + fun ClassDef.merge(otherClass: ClassDef, context: BytecodeContext) = this + //.fixFieldAccess(otherClass) + //.fixMethodAccess(otherClass) + .addMissingFields(otherClass) + .addMissingMethods(otherClass) + .publicize(otherClass, context) /** * Add methods which are missing but existing in [fromClass]. * * @param fromClass The class to add missing methods from. - * @param logger A logger. */ - private fun ClassDef.addMissingMethods(fromClass: ClassDef, logger: Logger? = null): ClassDef { + private fun ClassDef.addMissingMethods(fromClass: ClassDef): ClassDef { val missingMethods = fromClass.methods.let { fromMethods -> methods.filterNot { method -> fromMethods.any { fromMethod -> @@ -57,7 +57,7 @@ internal object ClassMerger { if (missingMethods.isEmpty()) return this - logger?.trace("Found ${missingMethods.size} missing methods") + logger.fine("Found ${missingMethods.size} missing methods") return asMutableClass().apply { methods.addAll(missingMethods.map { it.toMutable() }) @@ -68,16 +68,15 @@ internal object ClassMerger { * Add fields which are missing but existing in [fromClass]. * * @param fromClass The class to add missing fields from. - * @param logger A logger. */ - private fun ClassDef.addMissingFields(fromClass: ClassDef, logger: Logger? = null): ClassDef { + private fun ClassDef.addMissingFields(fromClass: ClassDef): ClassDef { val missingFields = fields.filterNotAny(fromClass.fields) { field, fromField -> fromField.name == field.name } if (missingFields.isEmpty()) return this - logger?.trace("Found ${missingFields.size} missing fields") + logger.fine("Found ${missingFields.size} missing fields") return asMutableClass().apply { fields.addAll(missingFields.map { it.toMutable() }) @@ -88,15 +87,14 @@ internal object ClassMerger { * Make a class and its super class public recursively. * @param reference The class to check the [AccessFlags] of. * @param context The context to traverse the class hierarchy in. - * @param logger A logger. */ - private fun ClassDef.publicize(reference: ClassDef, context: BytecodeContext, logger: Logger? = null) = + private fun ClassDef.publicize(reference: ClassDef, context: BytecodeContext) = if (reference.accessFlags.isPublic() && !accessFlags.isPublic()) this.asMutableClass().apply { context.traverseClassHierarchy(this) { if (accessFlags.isPublic()) return@traverseClassHierarchy - logger?.trace("Publicizing ${this.type}") + logger.fine("Publicizing ${this.type}") accessFlags = accessFlags.toPublic() } @@ -107,9 +105,8 @@ internal object ClassMerger { * Publicize fields if they are public in [reference]. * * @param reference The class to check the [AccessFlags] of the fields in. - * @param logger A logger. */ - private fun ClassDef.fixFieldAccess(reference: ClassDef, logger: Logger? = null): ClassDef { + private fun ClassDef.fixFieldAccess(reference: ClassDef): ClassDef { val brokenFields = fields.filterAny(reference.fields) { field, referenceField -> if (field.name != referenceField.name) return@filterAny false @@ -118,7 +115,7 @@ internal object ClassMerger { if (brokenFields.isEmpty()) return this - logger?.trace("Found ${brokenFields.size} broken fields") + logger.fine("Found ${brokenFields.size} broken fields") /** * Make a field public. @@ -136,9 +133,8 @@ internal object ClassMerger { * Publicize methods if they are public in [reference]. * * @param reference The class to check the [AccessFlags] of the methods in. - * @param logger A logger. */ - private fun ClassDef.fixMethodAccess(reference: ClassDef, logger: Logger? = null): ClassDef { + private fun ClassDef.fixMethodAccess(reference: ClassDef): ClassDef { val brokenMethods = methods.filterAny(reference.methods) { method, referenceMethod -> if (!MethodUtil.methodSignaturesMatch(method, referenceMethod)) return@filterAny false @@ -147,7 +143,7 @@ internal object ClassMerger { if (brokenMethods.isEmpty()) return this - logger?.trace("Found ${brokenMethods.size} methods") + logger.fine("Found ${brokenMethods.size} methods") /** * Make a method public. @@ -194,7 +190,6 @@ internal object ClassMerger { /** * Filter [this] on [needles] matching the given [predicate]. * - * @param this The hay to filter for [needles]. * @param needles The needles to filter [this] with. * @param predicate The filter. * @return The [this] filtered on [needles] matching the given [predicate]. @@ -206,7 +201,6 @@ internal object ClassMerger { /** * Filter [this] on [needles] not matching the given [predicate]. * - * @param this The hay to filter for [needles]. * @param needles The needles to filter [this] with. * @param predicate The filter. * @return The [this] filtered on [needles] not matching the given [predicate].