From bdc54ef318e328be48f63f9443fe30df1a165712 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 13 Feb 2024 03:29:21 +0100 Subject: [PATCH] build: Bump dependencies This commit also migrates away from deprecated to new APIs --- api/revanced-patches.api | 1 + .../exportall/ExportAllActivitiesPatch.kt | 19 +- .../gestures/PredictiveBackGesturePatch.kt | 6 +- .../debugging/EnableAndroidDebuggingPatch.kt | 12 +- .../OverrideCertificatePinningPatch.kt | 14 +- .../packagename/ChangePackageNamePatch.kt | 50 +++--- .../all/misc/resources/AddResourcesPatch.kt | 165 +++++++++--------- .../BaseTransformInstructionsPatch.kt | 4 +- .../RemoveCaptureRestrictionResourcePatch.kt | 13 +- .../fingerprints/ExclusiveAudioFingerprint.kt | 51 ------ .../fingerprints/ServiceCheckFingerprint.kt | 4 +- .../misc/integrations/IntegrationsPatch.kt | 5 +- .../RemoveBroadcastsRestrictionPatch.kt | 15 +- .../reddit/ad/banner/HideBannerPatch.kt | 5 +- .../gms/BaseGmsCoreSupportResourcePatch.kt | 61 ++++--- .../misc/mapping/ResourceMappingPatch.kt | 9 +- .../settings/BaseSettingsResourcePatch.kt | 16 +- .../spotify/layout/theme/CustomThemePatch.kt | 39 +++-- .../tiktok/misc/spoof/sim/SpoofSimPatch.kt | 14 +- .../patches/tumblr/ads/DisableDashboardAds.kt | 10 +- .../inappupdate/DisableInAppUpdatePatch.kt | 6 +- .../tumblr/live/DisableTumblrLivePatch.kt | 6 +- .../misc/dynamiccolor/DynamicColorPatch.kt | 18 +- .../twitter/misc/hook/patch/BaseHookPatch.kt | 4 +- .../youtube/ad/general/HideAdsPatch.kt | 30 ++-- .../copyvideourl/CopyVideoUrlBytecodePatch.kt | 19 +- .../ExternalDownloadsBytecodePatch.kt | 21 ++- .../layout/branding/CustomBrandingPatch.kt | 4 +- .../branding/header/ChangeHeaderPatch.kt | 4 +- .../buttons/cast/HideCastButtonPatch.kt | 10 +- .../PlayerControlsBackgroundPatch.kt | 15 +- .../seekbar/SeekbarColorResourcePatch.kt | 14 +- .../sponsorblock/SponsorBlockResourcePatch.kt | 47 +++-- .../layout/theme/ThemeResourcePatch.kt | 56 +++--- .../BottomControlsResourcePatch.kt | 33 ++-- .../misc/settings/SettingsResourcePatch.kt | 34 ++-- .../youtube/video/speed/PlaybackSpeedPatch.kt | 13 +- .../kotlin/app/revanced/util/ResourceUtils.kt | 73 +++++--- 38 files changed, 464 insertions(+), 456 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 25de72baa..0cb9c02f8 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1736,6 +1736,7 @@ public final class app/revanced/util/ResourceUtilsKt { public static final fun asSequence (Lorg/w3c/dom/NodeList;)Lkotlin/sequences/Sequence; public static final fun childElementsSequence (Lorg/w3c/dom/Node;)Lkotlin/sequences/Sequence; public static final fun copyResources (Lapp/revanced/patcher/data/ResourceContext;Ljava/lang/String;[Lapp/revanced/util/ResourceGroup;)V + public static final fun copyXmlNode (Ljava/lang/String;Lapp/revanced/patcher/util/Document;Lapp/revanced/patcher/util/Document;)Ljava/lang/AutoCloseable; public static final fun copyXmlNode (Ljava/lang/String;Lapp/revanced/patcher/util/DomFileEditor;Lapp/revanced/patcher/util/DomFileEditor;)Ljava/lang/AutoCloseable; public static final fun doRecursively (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V public static final fun forEachChildElement (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V diff --git a/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt b/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt index e9a38f533..88bcc6ece 100644 --- a/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt @@ -7,29 +7,32 @@ import app.revanced.patcher.patch.annotation.Patch @Patch( name = "Export all activities", description = "Makes all app activities exportable.", - use = false + use = false, ) @Suppress("unused") object ExportAllActivitiesPatch : ResourcePatch() { private const val EXPORTED_FLAG = "android:exported" + override fun execute(context: ResourceContext) { - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val document = editor.file + context.document["AndroidManifest.xml"].use { document -> val activities = document.getElementsByTagName("activity") - for(i in 0..activities.length) { + for (i in 0..activities.length) { activities.item(i)?.apply { val exportedAttribute = attributes.getNamedItem(EXPORTED_FLAG) if (exportedAttribute != null) { - if (exportedAttribute.nodeValue != "true") + if (exportedAttribute.nodeValue != "true") { exportedAttribute.nodeValue = "true" + } } // Reason why the attribute is added in the case it does not exist: // https://github.com/revanced/revanced-patches/pull/1751/files#r1141481604 - else document.createAttribute(EXPORTED_FLAG) - .apply { value = "true" } - .let(attributes::setNamedItem) + else { + document.createAttribute(EXPORTED_FLAG) + .apply { value = "true" } + .let(attributes::setNamedItem) + } } } } diff --git a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt b/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt index 3f3a0b9d5..d0c08751c 100644 --- a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt @@ -7,16 +7,14 @@ import app.revanced.patcher.patch.annotation.Patch @Patch( name = "Predictive back gesture", description = "Enables the predictive back gesture introduced on Android 13.", - use = false + use = false, ) @Suppress("unused") object PredictiveBackGesturePatch : ResourcePatch() { private const val FLAG = "android:enableOnBackInvokedCallback" override fun execute(context: ResourceContext) { - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val document = editor.file - + context.document["AndroidManifest.xml"].use { document -> with(document.getElementsByTagName("application").item(0)) { if (attributes.getNamedItem(FLAG) != null) return@with diff --git a/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt index 902205e61..94605fb7c 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt @@ -8,16 +8,16 @@ import org.w3c.dom.Element @Patch( name = "Enable Android debugging", description = "Enables Android debugging capabilities. This can slow down the app.", - use = false + use = false, ) @Suppress("unused") object EnableAndroidDebuggingPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - context.xmlEditor["AndroidManifest.xml"].use { dom -> - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element + context.document["AndroidManifest.xml"].use { document -> + val applicationNode = + document + .getElementsByTagName("application") + .item(0) as Element // set application as debuggable applicationNode.setAttribute("android:debuggable", "true") diff --git a/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt index d44033185..5bf14484d 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt @@ -11,16 +11,15 @@ import java.io.File name = "Override certificate pinning", description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.", dependencies = [EnableAndroidDebuggingPatch::class], - use = false + use = false, ) @Suppress("unused") object OverrideCertificatePinningPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - val resXmlDirectory = context["res/xml"] + val resXmlDirectory = context.get("res/xml", false) // Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist. - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val document = editor.file + context.document["AndroidManifest.xml"].use { document -> val applicationNode = document.getElementsByTagName("application").item(0) as Element if (!applicationNode.hasAttribute("networkSecurityConfig")) { @@ -54,7 +53,7 @@ object OverrideCertificatePinningPatch : ResourcePatch() { - """ + """, ) } else { // If the file already exists. @@ -63,12 +62,11 @@ object OverrideCertificatePinningPatch : ResourcePatch() { writeText( text.replace( "", - "\n\n" - ) + "\n\n", + ), ) } } - } } } diff --git a/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt index ea847c4d7..63d4bb2a2 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt @@ -11,20 +11,21 @@ import java.io.Closeable @Patch( name = "Change package name", description = "Appends \".revanced\" to the package name by default. Changing the package name of the app can lead to unexpected issues.", - use = false + use = false, ) @Suppress("unused") object ChangePackageNamePatch : ResourcePatch(), Closeable { - private val packageNameOption = stringPatchOption( - key = "packageName", - default = "Default", - values = mapOf("Default" to "Default"), - title = "Package name", - description = "The name of the package to rename the app to.", - required = true - ) { - it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) - } + private val packageNameOption = + stringPatchOption( + key = "packageName", + default = "Default", + values = mapOf("Default" to "Default"), + title = "Package name", + description = "The name of the package to rename the app to.", + required = true, + ) { + it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) + } private lateinit var context: ResourceContext @@ -43,20 +44,25 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable { fun setOrGetFallbackPackageName(fallbackPackageName: String): String { val packageName = packageNameOption.value!! - return if (packageName == packageNameOption.default) + return if (packageName == packageNameOption.default) { fallbackPackageName.also { packageNameOption.value = it } - else + } else { packageName + } } - override fun close() = context.xmlEditor["AndroidManifest.xml"].use { editor -> - val replacementPackageName = packageNameOption.value + override fun close() = + context.document["AndroidManifest.xml"].use { document -> + val replacementPackageName = packageNameOption.value - val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element - manifest.setAttribute( - "package", - if (replacementPackageName != packageNameOption.default) replacementPackageName - else "${manifest.getAttribute("package")}.revanced" - ) - } + val manifest = document.getElementsByTagName("manifest").item(0) as Element + manifest.setAttribute( + "package", + if (replacementPackageName != packageNameOption.default) { + replacementPackageName + } else { + "${manifest.getAttribute("package")}.revanced" + }, + ) + } } diff --git a/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt index bb72c077d..0baf671fc 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.DomFileEditor +import app.revanced.patcher.util.Document import app.revanced.patches.all.misc.resources.AddResourcesPatch.resources import app.revanced.util.* import app.revanced.util.resource.ArrayResource @@ -19,6 +19,7 @@ import java.util.* * An identifier of an app. For example, `youtube`. */ private typealias AppId = String + /** * An identifier of a patch. For example, `ad.general.HideAdsPatch`. */ @@ -28,10 +29,12 @@ private typealias PatchId = String * A set of resources of a patch. */ private typealias PatchResources = MutableSet + /** * A map of resources belonging to a patch. */ private typealias AppResources = MutableMap + /** * A map of resources belonging to an app. */ @@ -67,40 +70,42 @@ object AddResourcesPatch : ResourcePatch(), MutableMap/.xml` into the map. - * - * @param value The value of the resource. For example, `values` or `values-de`. - * @param resourceKind The kind of the resource. For example, `strings` or `arrays`. - * @param transform A function that transforms the [Node]s from the XML files to a [BaseResource]. - */ - fun addResources( - value: Value, - resourceKind: String, - transform: (Node) -> BaseResource, - ) { - inputStreamFromBundledResource( - "addresources", - "$value/$resourceKind.xml" - )?.let { stream -> - // Add the resources associated with the given value to the map, - // instead of overwriting it. - // This covers the example case such as adding strings and arrays of the same value. - getOrPut(value, ::mutableMapOf).apply { - context.xmlEditor[stream].use { - it.file.getElementsByTagName("app").asSequence().forEach { app -> - val appId = app.attributes.getNamedItem("id").textContent + resources = + buildMap { + /** + * Puts resources under `/resources/addresources//.xml` into the map. + * + * @param value The value of the resource. For example, `values` or `values-de`. + * @param resourceKind The kind of the resource. For example, `strings` or `arrays`. + * @param transform A function that transforms the [Node]s from the XML files to a [BaseResource]. + */ + fun addResources( + value: Value, + resourceKind: String, + transform: (Node) -> BaseResource, + ) { + inputStreamFromBundledResource( + "addresources", + "$value/$resourceKind.xml", + )?.let { stream -> + // Add the resources associated with the given value to the map, + // instead of overwriting it. + // This covers the example case such as adding strings and arrays of the same value. + getOrPut(value, ::mutableMapOf).apply { + context.document[stream].use { + it.getElementsByTagName("app").asSequence().forEach { app -> + val appId = app.attributes.getNamedItem("id").textContent - getOrPut(appId, ::mutableMapOf).apply { - app.forEachChildElement { patch -> - val patchId = patch.attributes.getNamedItem("id").textContent + getOrPut(appId, ::mutableMapOf).apply { + app.forEachChildElement { patch -> + val patchId = patch.attributes.getNamedItem("id").textContent - getOrPut(patchId, ::mutableSetOf).apply { - patch.forEachChildElement { resourceNode -> - val resource = transform(resourceNode) + getOrPut(patchId, ::mutableSetOf).apply { + patch.forEachChildElement { resourceNode -> + val resource = transform(resourceNode) - add(resource) + add(resource) + } } } } @@ -109,23 +114,22 @@ object AddResourcesPatch : ResourcePatch(), MutableMap - addResources(value, "strings", StringResource::fromNode) + // Stage all resources to a temporary map. + // Staged resources consumed by AddResourcesPatch#invoke(PatchClass) + // are later used in AddResourcesPatch#close. + try { + val addStringResources = { value: Value -> + addResources(value, "strings", StringResource::fromNode) + } + Locale.getISOLanguages().asSequence().map { "values-$it" }.forEach { addStringResources(it) } + addStringResources("values") + + addResources("values", "arrays", ArrayResource::fromNode) + } catch (e: Exception) { + throw PatchException("Failed to read resources", e) } - Locale.getISOLanguages().asSequence().map { "values-$it" }.forEach { addStringResources(it) } - addStringResources("values") - - addResources("values", "arrays", ArrayResource::fromNode) - } catch (e: Exception) { - throw PatchException("Failed to read resources", e) } - } } /** @@ -136,8 +140,10 @@ object AddResourcesPatch : ResourcePatch(), MutableMap) = - getOrPut(value, ::mutableSetOf).addAll(resources) + operator fun invoke( + value: Value, + resources: Iterable, + ) = getOrPut(value, ::mutableSetOf).addAll(resources) /** * Adds a [StringResource]. @@ -177,10 +185,9 @@ object AddResourcesPatch : ResourcePatch(), MutableMap + items: List, ) = invoke("values", ArrayResource(name, items)) - /** * Puts all resources of any [Value] staged in [resources] for the given [PatchClass] to [AddResourcesPatch]. * @@ -209,7 +216,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap resources[appId]?.get(patchId)?.let { patchResources -> - if (invoke(value, patchResources)) result = true + if (invoke(value, patchResources)) result = true } } @@ -230,30 +237,32 @@ object AddResourcesPatch : ResourcePatch(), MutableMap>.invoke( + operator fun MutableMap>.invoke( value: Value, - resource: BaseResource + resource: BaseResource, ) { // TODO: Fix open-closed principle violation by modifying BaseResource#serialize so that it accepts - // a Value and the map of editors. It will then get or put the editor suitable for its resource type + // a Value and the map of documents. It will then get or put the document suitable for its resource type // to serialize itself to it. - val resourceFileName = when (resource) { - is StringResource -> "strings" - is ArrayResource -> "arrays" - else -> throw NotImplementedError("Unsupported resource type") - } - - getOrPut(resourceFileName) { - val targetFile = context["res/$value/$resourceFileName.xml"].also { - it.parentFile?.mkdirs() - it.createNewFile() + val resourceFileName = + when (resource) { + is StringResource -> "strings" + is ArrayResource -> "arrays" + else -> throw NotImplementedError("Unsupported resource type") } - context.xmlEditor[targetFile.path].let { editor -> + getOrPut(resourceFileName) { + val targetFile = + context.get("res/$value/$resourceFileName.xml", false).also { + it.parentFile?.mkdirs() + it.createNewFile() + } + + context.document[targetFile.path].let { document -> // Save the target node here as well - // in order to avoid having to call editor.getNode("resources") - // every time addUsingEditors is called but also save the editor so that it can be closed later. - editor to editor.getNode("resources") + // in order to avoid having to call document.getNode("resources") + // but also save the document so that it can be closed later. + document to document.getNode("resources") } }.let { (_, targetNode) -> targetNode.addResource(resource) { invoke(value, it) } @@ -261,17 +270,17 @@ object AddResourcesPatch : ResourcePatch(), MutableMap - // A map of editors associated by their kind (e.g. strings, arrays). - // Each editor is accompanied by the target node to which resources are added. - // A map is used because Map#getOrPut allows opening a new editor for the duration of a resource value. + // A map of document associated by their kind (e.g. strings, arrays). + // Each document is accompanied by the target node to which resources are added. + // A map is used because Map#getOrPut allows opening a new document for the duration of a resource value. // This is done to prevent having to open the files for every resource that is added. // Instead, it is cached once and reused for resources of the same value. - // This map is later accessed to close all editors for the current resource value. - val resourceFileEditors = mutableMapOf>() + // This map is later accessed to close all documents for the current resource value. + val documents = mutableMapOf>() - resources.forEach { resource -> resourceFileEditors(value, resource) } + resources.forEach { resource -> documents(value, resource) } - resourceFileEditors.values.forEach { (editor, _) -> editor.close() } + documents.values.forEach { (document, _) -> document.close() } } } } diff --git a/src/main/kotlin/app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch.kt index 68e8a68ba..e651c4d63 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch.kt @@ -9,12 +9,12 @@ import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.Instruction @Suppress("MemberVisibilityCanBePrivate") -abstract class BaseTransformInstructionsPatch : BytecodePatch() { +abstract class BaseTransformInstructionsPatch : BytecodePatch(emptySet()) { abstract fun filterMap( classDef: ClassDef, method: Method, instruction: Instruction, - instructionIndex: Int + instructionIndex: Int, ): T? abstract fun transform(mutableMethod: MutableMethod, entry: T) diff --git a/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt b/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt index bd602f455..f38ce36f8 100644 --- a/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt @@ -8,16 +8,15 @@ import org.w3c.dom.Element @Patch(description = "Sets allowAudioPlaybackCapture in manifest to true.") internal object RemoveCaptureRestrictionResourcePatch : ResourcePatch() { override fun execute(context: ResourceContext) { - // create an xml editor instance - context.xmlEditor["AndroidManifest.xml"].use { dom -> + context.document["AndroidManifest.xml"].use { document -> // get the application node - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element + val applicationNode = + document + .getElementsByTagName("application") + .item(0) as Element // set allowAudioPlaybackCapture attribute to true applicationNode.setAttribute("android:allowAudioPlaybackCapture", "true") } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt deleted file mode 100644 index db2e2f0e4..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.music.audio.exclusiveaudio.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -internal object ExclusiveAudioFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L", "Z"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQ, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.NOP, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/ServiceCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/ServiceCheckFingerprint.kt index ca8db2046..536048502 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/ServiceCheckFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/ServiceCheckFingerprint.kt @@ -1,14 +1,12 @@ package app.revanced.patches.music.misc.gms.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags - internal object ServiceCheckFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "I"), - strings = listOf("Google Play Services not available") + strings = listOf("Google Play Services not available"), ) diff --git a/src/main/kotlin/app/revanced/patches/music/misc/integrations/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/integrations/IntegrationsPatch.kt index 06f45d7e9..ab061458f 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/integrations/IntegrationsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/integrations/IntegrationsPatch.kt @@ -6,8 +6,5 @@ import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch @Patch(requiresIntegrations = true) object IntegrationsPatch : BaseIntegrationsPatch( - "Lapp/revanced/integrations/utils/ReVancedUtils;", - setOf( - ApplicationInitFingerprint, - ), + setOf(ApplicationInitFingerprint), ) diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt index dc06778f2..7afd50631 100644 --- a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt @@ -6,23 +6,22 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import org.w3c.dom.Element - @Patch( name = "Remove broadcasts restriction", description = "Enables starting/stopping NetGuard via broadcasts.", compatiblePackages = [CompatiblePackage("eu.faircode.netguard")], - use = false + use = false, ) @Suppress("unused") object RemoveBroadcastsRestrictionPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - context.xmlEditor["AndroidManifest.xml"].use { dom -> - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element + context.document["AndroidManifest.xml"].use { document -> + val applicationNode = + document + .getElementsByTagName("application") + .item(0) as Element - applicationNode.getElementsByTagName("receiver").also { list -> + applicationNode.getElementsByTagName("receiver").also { list -> for (i in 0 until list.length) { val element = list.item(i) as? Element ?: continue if (element.getAttribute("android:name") == "eu.faircode.netguard.WidgetAdmin") { diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt index 669d67b88..4e5a00904 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt @@ -9,8 +9,8 @@ object HideBannerPatch : ResourcePatch() { private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml" override fun execute(context: ResourceContext) { - context.xmlEditor[RESOURCE_FILE_PATH].use { - it.file.getElementsByTagName("merge").item(0).childNodes.apply { + context.document[RESOURCE_FILE_PATH].use { + it.getElementsByTagName("merge").item(0).childNodes.apply { val attributes = arrayOf("height", "width") for (i in 1 until length) { @@ -30,4 +30,3 @@ object HideBannerPatch : ResourcePatch() { } } } - diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt index cfd80488b..9e3d1a9ab 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt @@ -22,19 +22,21 @@ abstract class BaseGmsCoreSupportResourcePatch( private val fromPackageName: String, private val toPackageName: String, private val spoofedPackageSignature: String, - dependencies: Set = setOf() + dependencies: Set = setOf(), ) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) { - internal val gmsCoreVendorOption = stringPatchOption( - key = "gmsCoreVendor", - default = "com.mgoogle", - values = mapOf( - "Vanced" to "com.mgoogle", - "ReVanced" to "app.revanced" - ), - title = "GmsCore Vendor", - description = "The group id of the GmsCore vendor.", - required = true - ) { it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) } + internal val gmsCoreVendorOption = + stringPatchOption( + key = "gmsCoreVendor", + default = "com.mgoogle", + values = + mapOf( + "Vanced" to "com.mgoogle", + "ReVanced" to "app.revanced", + ), + title = "GmsCore Vendor", + description = "The group id of the GmsCore vendor.", + required = true, + ) { it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) } protected val gmsCoreVendor by gmsCoreVendorOption @@ -49,17 +51,20 @@ abstract class BaseGmsCoreSupportResourcePatch( * Add metadata to manifest to support spoofing the package name and signature of GmsCore. */ private fun ResourceContext.addSpoofingMetadata() { - fun Node.adoptChild(tagName: String, block: Element.() -> Unit) { + fun Node.adoptChild( + tagName: String, + block: Element.() -> Unit, + ) { val child = ownerDocument.createElement(tagName) child.block() appendChild(child) } - xmlEditor["AndroidManifest.xml"].use { - val applicationNode = it - .file - .getElementsByTagName("application") - .item(0) + document["AndroidManifest.xml"].use { document -> + val applicationNode = + document + .getElementsByTagName("application") + .item(0) // Spoof package name and signature. applicationNode.adoptChild("meta-data") { @@ -87,27 +92,27 @@ abstract class BaseGmsCoreSupportResourcePatch( private fun ResourceContext.patchManifest() { val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName) - val manifest = this["AndroidManifest.xml"].readText() - this["AndroidManifest.xml"].writeText( + val manifest = this.get("AndroidManifest.xml", false).readText() + this.get("AndroidManifest.xml", false).writeText( manifest.replace( "package=\"$fromPackageName", - "package=\"$packageName" + "package=\"$packageName", ).replace( "android:authorities=\"$fromPackageName", - "android:authorities=\"$packageName" + "android:authorities=\"$packageName", ).replace( "$fromPackageName.permission.C2D_MESSAGE", - "$packageName.permission.C2D_MESSAGE" + "$packageName.permission.C2D_MESSAGE", ).replace( "$fromPackageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", - "$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" + "$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", ).replace( "com.google.android.c2dm", - "$gmsCoreVendor.android.c2dm" + "$gmsCoreVendor.android.c2dm", ).replace( "", - "" - ) + "", + ), ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt index c3b1ef20a..9b27144d6 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt @@ -7,7 +7,6 @@ import java.util.* import java.util.concurrent.Executors import java.util.concurrent.TimeUnit - object ResourceMappingPatch : ResourcePatch() { internal lateinit var resourceMappings: List private set @@ -17,15 +16,15 @@ object ResourceMappingPatch : ResourcePatch() { override fun execute(context: ResourceContext) { // save the file in memory to concurrently read from - val resourceXmlFile = context["res/values/public.xml"].readBytes() + val resourceXmlFile = context.get("res/values/public.xml", false).readBytes() // create a synchronized list to store the resource mappings val mappings = Collections.synchronizedList(mutableListOf()) for (threadIndex in 0 until THREAD_COUNT) { threadPoolExecutor.execute thread@{ - context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> - val resources = editor.file.documentElement.childNodes + context.document[resourceXmlFile.inputStream()].use { document -> + val resources = document.documentElement.childNodes val resourcesLength = resources.length val jobSize = resourcesLength / THREAD_COUNT @@ -59,4 +58,4 @@ object ResourceMappingPatch : ResourcePatch() { } data class ResourceElement(val type: String, val name: String, val id: Long) -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt index d54601dae..5ad4195c2 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt @@ -21,16 +21,18 @@ import java.io.Closeable */ abstract class BaseSettingsResourcePatch( private val rootPreference: Pair? = null, - dependencies: Set = emptySet() + dependencies: Set = emptySet(), ) : ResourcePatch( - dependencies = setOf(AddResourcesPatch::class) + dependencies -), MutableSet by mutableSetOf(), Closeable { + dependencies = setOf(AddResourcesPatch::class) + dependencies, + ), + MutableSet by mutableSetOf(), + Closeable { private lateinit var context: ResourceContext override fun execute(context: ResourceContext) { context.copyResources( "settings", - ResourceGroup("xml", "revanced_prefs.xml") + ResourceGroup("xml", "revanced_prefs.xml"), ) this.context = context @@ -49,14 +51,14 @@ abstract class BaseSettingsResourcePatch( // Add the root preference to an existing fragment if needed. rootPreference?.let { (intentPreference, fragment) -> - context.xmlEditor["res/xml/$fragment.xml"].use { + context.document["res/xml/$fragment.xml"].use { it.getNode("PreferenceScreen").addPreference(intentPreference) } } // Add all preferences to the ReVanced fragment. - context.xmlEditor["res/xml/revanced_prefs.xml"].use { editor -> - val revancedPreferenceScreenNode = editor.getNode("PreferenceScreen") + context.document["res/xml/revanced_prefs.xml"].use { document -> + val revancedPreferenceScreenNode = document.getNode("PreferenceScreen") forEach { revancedPreferenceScreenNode.addPreference(it) } } } diff --git a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt index 1faeae0ae..2d839f168 100644 --- a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt +++ b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt @@ -10,7 +10,7 @@ import org.w3c.dom.Element @Patch( name = "Custom theme", description = "Applies a custom theme.", - compatiblePackages = [CompatiblePackage("com.spotify.music")] + compatiblePackages = [CompatiblePackage("com.spotify.music")], ) @Suppress("unused") object CustomThemePatch : ResourcePatch() { @@ -19,7 +19,7 @@ object CustomThemePatch : ResourcePatch() { default = "@android:color/black", title = "Primary background color", description = "The background color. Can be a hex color or a resource reference.", - required = true + required = true, ) private var backgroundColorSecondary by stringPatchOption( @@ -27,7 +27,7 @@ object CustomThemePatch : ResourcePatch() { default = "#ff282828", title = "Secondary background color", description = "The secondary background color. (e.g. search box, artist & podcast). Can be a hex color or a resource reference.", - required = true + required = true, ) private var accentColor by stringPatchOption( @@ -35,16 +35,17 @@ object CustomThemePatch : ResourcePatch() { default = "#ff1ed760", title = "Accent color", description = "The accent color ('Spotify green' by default). Can be a hex color or a resource reference.", - required = true + required = true, ) private var accentColorPressed by stringPatchOption( key = "accentColorPressed", default = "#ff169c46", title = "Pressed dark theme accent color", - description = "The color when accented buttons are pressed, by default slightly darker than accent. " - + "Can be a hex color or a resource reference.", - required = true + description = + "The color when accented buttons are pressed, by default slightly darker than accent. " + + "Can be a hex color or a resource reference.", + required = true, ) override fun execute(context: ResourceContext) { @@ -53,24 +54,26 @@ object CustomThemePatch : ResourcePatch() { val accentColor = accentColor!! val accentColorPressed = accentColorPressed!! - context.xmlEditor["res/values/colors.xml"].use { editor -> - val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element + context.document["res/values/colors.xml"].use { document -> + val resourcesNode = document.getElementsByTagName("resources").item(0) as Element for (i in 0 until resourcesNode.childNodes.length) { val node = resourcesNode.childNodes.item(i) as? Element ?: continue - node.textContent = when (node.getAttribute("name")) { - "dark_base_background_elevated_base", "design_dark_default_color_background", - "design_dark_default_color_surface", "gray_7", "gray_background", "gray_layer", - "sthlm_blk" -> backgroundColor + node.textContent = + when (node.getAttribute("name")) { + "dark_base_background_elevated_base", "design_dark_default_color_background", + "design_dark_default_color_surface", "gray_7", "gray_background", "gray_layer", + "sthlm_blk", + -> backgroundColor - "gray_15" -> backgroundColorSecondary + "gray_15" -> backgroundColorSecondary - "dark_brightaccent_background_base", "dark_base_text_brightaccent", "green_light" -> accentColor + "dark_brightaccent_background_base", "dark_base_text_brightaccent", "green_light" -> accentColor - "dark_brightaccent_background_press" -> accentColorPressed - else -> continue - } + "dark_brightaccent_background_press" -> accentColorPressed + else -> continue + } } } } diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt index 39d412d26..1c40b5d9c 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt @@ -23,19 +23,19 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference dependencies = [IntegrationsPatch::class, SettingsPatch::class], compatiblePackages = [ CompatiblePackage("com.ss.android.ugc.trill"), - CompatiblePackage("com.zhiliaoapp.musically") + CompatiblePackage("com.zhiliaoapp.musically"), ], - use = false + use = false, ) @Suppress("unused") -object SpoofSimPatch : BytecodePatch() { +object SpoofSimPatch : BytecodePatch(emptySet()) { private val replacements = hashMapOf( "getSimCountryIso" to "getCountryIso", "getNetworkCountryIso" to "getCountryIso", "getSimOperator" to "getOperator", "getNetworkOperator" to "getOperator", "getSimOperatorName" to "getOperatorName", - "getNetworkOperatorName" to "getOperatorName" + "getNetworkOperatorName" to "getOperatorName", ) override fun execute(context: BytecodeContext) { @@ -85,7 +85,7 @@ object SpoofSimPatch : BytecodePatch() { with(SettingsStatusLoadFingerprint.result!!.mutableMethod) { addInstruction( 0, - "invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableSimSpoof()V" + "invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableSimSpoof()V", ) } } @@ -99,7 +99,7 @@ object SpoofSimPatch : BytecodePatch() { """ invoke-static {v$resultReg}, Lapp/revanced/integrations/tiktok/spoof/sim/SpoofSimPatch;->$replacement(Ljava/lang/String;)Ljava/lang/String; move-result-object v$resultReg - """ + """, ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/tumblr/ads/DisableDashboardAds.kt b/src/main/kotlin/app/revanced/patches/tumblr/ads/DisableDashboardAds.kt index 09972604a..77d31b9f3 100644 --- a/src/main/kotlin/app/revanced/patches/tumblr/ads/DisableDashboardAds.kt +++ b/src/main/kotlin/app/revanced/patches/tumblr/ads/DisableDashboardAds.kt @@ -10,11 +10,11 @@ import app.revanced.patches.tumblr.timelinefilter.TimelineFilterPatch name = "Disable dashboard ads", description = "Disables ads in the dashboard.", compatiblePackages = [CompatiblePackage("com.tumblr")], - dependencies = [TimelineFilterPatch::class] + dependencies = [TimelineFilterPatch::class], ) @Suppress("unused") -object DisableDashboardAds : BytecodePatch() { - override fun execute(context: BytecodeContext) { +object DisableDashboardAds : BytecodePatch(emptySet()) { + override fun execute(context: BytecodeContext) { // The timeline object types are filtered by their name in the TimelineObjectType enum. // This is often different from the "object_type" returned in the api (noted in comments here) arrayOf( @@ -29,9 +29,9 @@ object DisableDashboardAds : BytecodePatch() { "DISPLAY_IO_INTERSCROLLER_AD", // "display_io_interscroller" "DISPLAY_IO_HEADLINE_VIDEO_AD", // "display_io_headline_video" "FACEBOOK_BIDDAABLE", // "facebook_biddable_sdk_ad" - "GOOGLE_NATIVE" // "google_native_ad" + "GOOGLE_NATIVE", // "google_native_ad" ).forEach { TimelineFilterPatch.addObjectTypeFilter(it) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/tumblr/annoyances/inappupdate/DisableInAppUpdatePatch.kt b/src/main/kotlin/app/revanced/patches/tumblr/annoyances/inappupdate/DisableInAppUpdatePatch.kt index 574f5c383..c9664d544 100644 --- a/src/main/kotlin/app/revanced/patches/tumblr/annoyances/inappupdate/DisableInAppUpdatePatch.kt +++ b/src/main/kotlin/app/revanced/patches/tumblr/annoyances/inappupdate/DisableInAppUpdatePatch.kt @@ -10,13 +10,13 @@ import app.revanced.patches.tumblr.featureflags.OverrideFeatureFlagsPatch name = "Disable in-app update", description = "Disables the in-app update check and update prompt.", dependencies = [OverrideFeatureFlagsPatch::class], - compatiblePackages = [CompatiblePackage("com.tumblr")] + compatiblePackages = [CompatiblePackage("com.tumblr")], ) @Suppress("unused") -object DisableInAppUpdatePatch : BytecodePatch() { +object DisableInAppUpdatePatch : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) { // Before checking for updates using Google Play core AppUpdateManager, the value of this feature flag is checked. // If this flag is false or the last update check was today and no update check is performed. OverrideFeatureFlagsPatch.addOverride("inAppUpdate", "false") } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/tumblr/live/DisableTumblrLivePatch.kt b/src/main/kotlin/app/revanced/patches/tumblr/live/DisableTumblrLivePatch.kt index 1c9ec2a83..8cbdaca6e 100644 --- a/src/main/kotlin/app/revanced/patches/tumblr/live/DisableTumblrLivePatch.kt +++ b/src/main/kotlin/app/revanced/patches/tumblr/live/DisableTumblrLivePatch.kt @@ -11,10 +11,10 @@ import app.revanced.patches.tumblr.timelinefilter.TimelineFilterPatch name = "Disable Tumblr Live", description = "Disable the Tumblr Live tab button and dashboard carousel.", dependencies = [OverrideFeatureFlagsPatch::class, TimelineFilterPatch::class], - compatiblePackages = [CompatiblePackage("com.tumblr")] + compatiblePackages = [CompatiblePackage("com.tumblr")], ) @Suppress("unused") -object DisableTumblrLivePatch : BytecodePatch() { +object DisableTumblrLivePatch : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) { // Hide the LIVE_MARQUEE timeline element that appears in the feed // Called "live_marquee" in api response @@ -23,4 +23,4 @@ object DisableTumblrLivePatch : BytecodePatch() { // Hide the Tab button for Tumblr Live by forcing the feature flag to false OverrideFeatureFlagsPatch.addOverride("liveStreaming", "false") } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt index 1d0a3326e..0b33fdc35 100644 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt +++ b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt @@ -11,12 +11,12 @@ import java.nio.file.Files @Patch( name = "Dynamic color", description = "Replaces the default X (Formerly Twitter) Blue with the user's Material You palette.", - compatiblePackages = [CompatiblePackage("com.twitter.android")] + compatiblePackages = [CompatiblePackage("com.twitter.android")], ) @Suppress("unused") object DynamicColorPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - val resDirectory = context["res"] + val resDirectory = context.get("res", false) if (!resDirectory.isDirectory) throw PatchException("The res folder can not be found.") val valuesV31Directory = resDirectory.resolve("values-v31") @@ -28,16 +28,14 @@ object DynamicColorPatch : ResourcePatch() { listOf(valuesV31Directory, valuesNightV31Directory).forEach { it -> val colorsXml = it.resolve("colors.xml") - if(!colorsXml.exists()) { + if (!colorsXml.exists()) { FileWriter(colorsXml).use { it.write("") } } } - context.xmlEditor["res/values-v31/colors.xml"].use { editor -> - val document = editor.file - + context.document["res/values-v31/colors.xml"].use { document -> mapOf( "ps__twitter_blue" to "@color/twitter_blue", "ps__twitter_blue_pressed" to "@color/twitter_blue_fill_pressed", @@ -46,7 +44,7 @@ object DynamicColorPatch : ResourcePatch() { "twitter_blue_opacity_30" to "@android:color/system_accent1_100", "twitter_blue_opacity_50" to "@android:color/system_accent1_200", "twitter_blue_opacity_58" to "@android:color/system_accent1_300", - "deep_transparent_twitter_blue" to "@android:color/system_accent1_200" + "deep_transparent_twitter_blue" to "@android:color/system_accent1_200", ).forEach { (k, v) -> val colorElement = document.createElement("color") @@ -57,16 +55,14 @@ object DynamicColorPatch : ResourcePatch() { } } - context.xmlEditor["res/values-night-v31/colors.xml"].use { editor -> - val document = editor.file - + context.document["res/values-night-v31/colors.xml"].use { document -> mapOf( "twitter_blue" to "@android:color/system_accent1_200", "twitter_blue_fill_pressed" to "@android:color/system_accent1_300", "twitter_blue_opacity_30" to "@android:color/system_accent1_50", "twitter_blue_opacity_50" to "@android:color/system_accent1_100", "twitter_blue_opacity_58" to "@android:color/system_accent1_200", - "deep_transparent_twitter_blue" to "@android:color/system_accent1_200" + "deep_transparent_twitter_blue" to "@android:color/system_accent1_200", ).forEach { (k, v) -> val colorElement = document.createElement("color") diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatch.kt index 74c83fb18..dace23012 100644 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatch.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.patch.BytecodePatch import app.revanced.patches.twitter.misc.hook.json.JsonHookPatch -abstract class BaseHookPatch(private val hookClassDescriptor: String) : BytecodePatch() { +abstract class BaseHookPatch(private val hookClassDescriptor: String) : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) = JsonHookPatch.hooks.addHook(JsonHookPatch.Hook(context, hookClassDescriptor)) -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt index d487bfeac..b73927b67 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt @@ -1,7 +1,5 @@ package app.revanced.patches.youtube.ad.general -import app.revanced.util.findMutableMethodOf -import app.revanced.util.injectHideViewCall import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage @@ -9,6 +7,8 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.shared.misc.fix.verticalscroll.VerticalScrollPatch import app.revanced.patches.youtube.ad.getpremium.HideGetPremiumPatch import app.revanced.patches.youtube.misc.fix.backtoexitgesture.FixBackToExitGesturePatch +import app.revanced.util.findMutableMethodOf +import app.revanced.util.injectHideViewCall import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c @@ -20,11 +20,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c HideGetPremiumPatch::class, HideAdsResourcePatch::class, VerticalScrollPatch::class, - FixBackToExitGesturePatch::class + FixBackToExitGesturePatch::class, ], compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.32.39", "18.37.36", "18.38.44", @@ -37,30 +38,33 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c "19.02.39", "19.03.35", "19.03.36", - "19.04.37" - ] - ) - ] + "19.04.37", + ], + ), + ], ) @Suppress("unused") -object HideAdsPatch : BytecodePatch() { +object HideAdsPatch : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) { context.classes.forEach { classDef -> classDef.methods.forEach { method -> with(method.implementation) { this?.instructions?.forEachIndexed { index, instruction -> - if (instruction.opcode != Opcode.CONST) + if (instruction.opcode != Opcode.CONST) { return@forEachIndexed + } // Instruction to store the id adAttribution into a register - if ((instruction as Instruction31i).wideLiteral != HideAdsResourcePatch.adAttributionId) + if ((instruction as Instruction31i).wideLiteral != HideAdsResourcePatch.adAttributionId) { return@forEachIndexed + } val insertIndex = index + 1 // Call to get the view with the id adAttribution with(instructions.elementAt(insertIndex)) { - if (opcode != Opcode.INVOKE_VIRTUAL) + if (opcode != Opcode.INVOKE_VIRTUAL) { return@forEachIndexed + } // Hide the view val viewRegister = (this as Instruction35c).registerC @@ -71,7 +75,7 @@ object HideAdsPatch : BytecodePatch() { insertIndex, viewRegister, "Lapp/revanced/integrations/youtube/patches/components/AdsFilter;", - "hideAdAttributionView" + "hideAdAttributionView", ) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt index 9d23802f7..894d30855 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt @@ -13,28 +13,29 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch dependencies = [ CopyVideoUrlResourcePatch::class, PlayerControlsBytecodePatch::class, - VideoInformationPatch::class + VideoInformationPatch::class, ], compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.48.39", "18.49.37", "19.01.34", "19.02.39", "19.03.35", "19.03.36", - "19.04.37" - ] - ) - ] + "19.04.37", + ], + ), + ], ) @Suppress("unused") -object CopyVideoUrlBytecodePatch : BytecodePatch() { +object CopyVideoUrlBytecodePatch : BytecodePatch(emptySet()) { private const val INTEGRATIONS_PLAYER_PACKAGE = "Lapp/revanced/integrations/youtube/videoplayer" private val BUTTONS_DESCRIPTORS = listOf( "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlButton;", - "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlTimestampButton;" + "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlTimestampButton;", ) override fun execute(context: BytecodeContext) { @@ -44,4 +45,4 @@ object CopyVideoUrlBytecodePatch : BytecodePatch() { PlayerControlsBytecodePatch.injectVisibilityCheckCall("$descriptor->changeVisibility(Z)V") } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt index 9a2bd645a..fdda9fdbe 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt @@ -13,24 +13,25 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch dependencies = [ ExternalDownloadsResourcePatch::class, PlayerControlsBytecodePatch::class, - VideoInformationPatch::class + VideoInformationPatch::class, ], compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.48.39", "18.49.37", "19.01.34", "19.02.39", "19.03.35", "19.03.36", - "19.04.37" - ] + "19.04.37", + ], ), - ] + ], ) @Suppress("unused") -object ExternalDownloadsBytecodePatch : BytecodePatch() { +object ExternalDownloadsBytecodePatch : BytecodePatch(emptySet()) { private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;" override fun execute(context: BytecodeContext) { @@ -39,13 +40,15 @@ object ExternalDownloadsBytecodePatch : BytecodePatch() { */ PlayerControlsBytecodePatch.initializeControl( - "$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V") + "$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V", + ) /* add code to change the visibility of the control */ PlayerControlsBytecodePatch.injectVisibilityCheckCall( - "$BUTTON_DESCRIPTOR->changeVisibility(Z)V") + "$BUTTON_DESCRIPTOR->changeVisibility(Z)V", + ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt index 19aa116b5..d0fc001e2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt @@ -81,7 +81,7 @@ object CustomBrandingPatch : ResourcePatch() { }.let { resourceGroups -> if (icon != REVANCED_ICON) { val path = File(icon) - val resourceDirectory = context["res"] + val resourceDirectory = context.get("res", false) resourceGroups.forEach { group -> val fromDirectory = path.resolve(group.resourceDirectoryName) @@ -102,7 +102,7 @@ object CustomBrandingPatch : ResourcePatch() { appName?.let { name -> // Change the app name. - val manifest = context["AndroidManifest.xml"] + val manifest = context.get("AndroidManifest.xml", false) manifest.writeText( manifest.readText() .replace( diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt index f02b982df..61fe82a16 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt @@ -71,7 +71,7 @@ object ChangeHeaderPatch : ResourcePatch() { override fun execute(context: ResourceContext) { // The directories to copy the header to. val targetResourceDirectories = targetResourceDirectoryNames.keys.mapNotNull { - context["res"].resolve(it).takeIf(File::exists) + context.get("res", false).resolve(it).takeIf(File::exists) } // The files to replace in the target directories. val targetResourceFiles = targetResourceDirectoryNames.keys.map { directoryName -> @@ -120,7 +120,7 @@ object ChangeHeaderPatch : ResourcePatch() { // For each source folder, copy the files to the target resource directories. sourceFolders.forEach { dpiSourceFolder -> - val targetDpiFolder = context["res"].resolve(dpiSourceFolder.name) + val targetDpiFolder = context.get("res", false).resolve(dpiSourceFolder.name) if (!targetDpiFolder.exists()) return@forEach val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!! diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/HideCastButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/HideCastButtonPatch.kt index ee1f6943a..24dda9fdf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/HideCastButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/HideCastButtonPatch.kt @@ -17,13 +17,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch dependencies = [ IntegrationsPatch::class, SettingsPatch::class, - AddResourcesPatch::class + AddResourcesPatch::class, ], compatiblePackages = [ - CompatiblePackage("com.google.android.youtube") - ] + CompatiblePackage("com.google.android.youtube"), + ], ) -object HideCastButtonPatch : BytecodePatch() { +object HideCastButtonPatch : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) { AddResourcesPatch(this::class) @@ -38,7 +38,7 @@ object HideCastButtonPatch : BytecodePatch() { """ invoke-static {p1}, Lapp/revanced/integrations/youtube/patches/HideCastButtonPatch;->getCastButtonOverrideV2(I)I move-result p1 - """ + """, ) } ?: throw PatchException("setVisibility method not found.") } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt index 66638a2bf..8c3d5a7b2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt @@ -12,7 +12,8 @@ import org.w3c.dom.Element description = "Removes the dark background surrounding the video player controls.", compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.32.39", "18.37.36", "18.38.44", @@ -25,19 +26,19 @@ import org.w3c.dom.Element "19.02.39", "19.03.35", "19.03.36", - "19.04.37" - ] - ) + "19.04.37", + ], + ), ], - use = false + use = false, ) @Suppress("unused") object PlayerControlsBackgroundPatch : ResourcePatch() { private const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml" override fun execute(context: ResourceContext) { - context.xmlEditor[RESOURCE_FILE_PATH].use { editor -> - editor.file.doRecursively node@{ node -> + context.document[RESOURCE_FILE_PATH].use { document -> + document.doRecursively node@{ node -> if (node !is Element) return@node node.getAttributeNode("android:color")?.let { attribute -> diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt index 5c7d6272a..cb70ee44c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt @@ -9,7 +9,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch import org.w3c.dom.Element @Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class]) -internal object SeekbarColorResourcePatch : ResourcePatch(){ +internal object SeekbarColorResourcePatch : ResourcePatch() { internal var reelTimeBarPlayedColorId = -1L internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L @@ -18,7 +18,7 @@ internal object SeekbarColorResourcePatch : ResourcePatch(){ fun findColorResource(resourceName: String): Long { return ResourceMappingPatch.resourceMappings .find { it.type == "color" && it.name == resourceName }?.id - ?: throw PatchException("Could not find color resource: $resourceName") + ?: throw PatchException("Could not find color resource: $resourceName") } reelTimeBarPlayedColorId = @@ -29,16 +29,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch(){ findColorResource("inline_time_bar_played_not_highlighted_color") // Edit the resume playback drawable and replace the progress bar with a custom drawable - context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> - val layerList = editor.file.getElementsByTagName("layer-list").item(0) as Element + context.document["res/drawable/resume_playback_progressbar_drawable.xml"].use { document -> + val layerList = document.getElementsByTagName("layer-list").item(0) as Element val progressNode = layerList.getElementsByTagName("item").item(1) as Element if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { throw PatchException("Could not find progress bar") } val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element - val replacementNode = editor.file.createElement( - "app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable") + val replacementNode = + document.createElement( + "app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable", + ) scaleNode.replaceChild(replacementNode, shapeNode) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt index a8c347b2c..272ce36e8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt @@ -17,26 +17,25 @@ import app.revanced.util.inputStreamFromBundledResource dependencies = [ SettingsPatch::class, ResourceMappingPatch::class, - AddResourcesPatch::class - ] + AddResourcesPatch::class, + ], ) internal object SponsorBlockResourcePatch : ResourcePatch() { - override fun execute(context: ResourceContext) { AddResourcesPatch(this::class) SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( IntentPreference( "revanced_sb_settings", - intent = SettingsPatch.newIntent("revanced_sb_settings_intent") - ) + intent = SettingsPatch.newIntent("revanced_sb_settings_intent"), + ), ) arrayOf( ResourceGroup( "layout", "revanced_sb_inline_sponsor_overlay.xml", "revanced_sb_new_segment.xml", - "revanced_sb_skip_sponsor_button.xml" + "revanced_sb_skip_sponsor_button.xml", ), ResourceGroup( // required resource for back button, because when the base APK is used, this resource will not exist @@ -46,37 +45,47 @@ internal object SponsorBlockResourcePatch : ResourcePatch() { "revanced_sb_edit.xml", "revanced_sb_logo.xml", "revanced_sb_publish.xml", - "revanced_sb_voting.xml" + "revanced_sb_voting.xml", ), ResourceGroup( // required resource for back button, because when the base APK is used, this resource will not exist - "drawable-xxxhdpi", "quantum_ic_skip_next_white_24.png" - ) + "drawable-xxxhdpi", + "quantum_ic_skip_next_white_24.png", + ), ).forEach { resourceGroup -> context.copyResources("sponsorblock", resourceGroup) } // copy nodes from host resources to their real xml files - val hostingResourceStream = inputStreamFromBundledResource( - "sponsorblock", - "host/layout/youtube_controls_layout.xml" - )!! + val hostingResourceStream = + inputStreamFromBundledResource( + "sponsorblock", + "host/layout/youtube_controls_layout.xml", + )!! var modifiedControlsLayout = false - val targetXmlEditor = context.xmlEditor["res/layout/youtube_controls_layout.xml"] + val targetDocument = context.document["res/layout/youtube_controls_layout.xml"] "RelativeLayout".copyXmlNode( - context.xmlEditor[hostingResourceStream], - targetXmlEditor + context.document[hostingResourceStream], + targetDocument, ).also { - val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes + val children = targetDocument.getElementsByTagName("RelativeLayout").item(0).childNodes // Replace the startOf with the voting button view so that the button does not overlap for (i in 1 until children.length) { val view = children.item(i) // Replace the attribute for a specific node only - if (!(view.hasAttributes() && view.attributes.getNamedItem("android:id").nodeValue.endsWith("live_chat_overlay_button"))) continue + if (!( + view.hasAttributes() && + view.attributes.getNamedItem( + "android:id", + ).nodeValue.endsWith("live_chat_overlay_button") + ) + ) { + continue + } // voting button id from the voting button view from the youtube_controls_layout.xml host file val votingButtonId = "@+id/revanced_sb_voting_button" @@ -90,4 +99,4 @@ internal object SponsorBlockResourcePatch : ResourcePatch() { if (!modifiedControlsLayout) throw PatchException("Could not modify controls layout") } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt index d379514e2..cf5e351cc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt @@ -20,8 +20,8 @@ import org.w3c.dom.Element SettingsPatch::class, ResourceMappingPatch::class, SeekbarPreferencesPatch::class, - AddResourcesPatch::class - ] + AddResourcesPatch::class, + ], ) internal object ThemeResourcePatch : ResourcePatch() { private const val SPLASH_BACKGROUND_COLOR = "revanced_splash_background_color" @@ -31,28 +31,29 @@ internal object ThemeResourcePatch : ResourcePatch() { SeekbarPreferencesPatch.addPreferences( SwitchPreference("revanced_seekbar_custom_color"), - TextPreference("revanced_seekbar_custom_color_value", inputType = InputType.TEXT_CAP_CHARACTERS) + TextPreference("revanced_seekbar_custom_color_value", inputType = InputType.TEXT_CAP_CHARACTERS), ) // Edit theme colors via resources. - context.xmlEditor["res/values/colors.xml"].use { editor -> - val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element + context.document["res/values/colors.xml"].use { document -> + val resourcesNode = document.getElementsByTagName("resources").item(0) as Element val children = resourcesNode.childNodes for (i in 0 until children.length) { val node = children.item(i) as? Element ?: continue - node.textContent = when (node.getAttribute("name")) { - "yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", - "yt_black4", "yt_status_bar_background_dark", "material_grey_850" - -> darkThemeBackgroundColor ?: continue + node.textContent = + when (node.getAttribute("name")) { + "yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", + "yt_black4", "yt_status_bar_background_dark", "material_grey_850", + -> darkThemeBackgroundColor ?: continue - "yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", - "yt_white2", "yt_white3", "yt_white4", - -> lightThemeBackgroundColor ?: continue + "yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", + "yt_white2", "yt_white3", "yt_white4", + -> lightThemeBackgroundColor ?: continue - else -> continue - } + else -> continue + } } } @@ -68,14 +69,15 @@ internal object ThemeResourcePatch : ResourcePatch() { // Edit splash screen files and change the background color, // if the background colors are set. if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) { - val splashScreenResourceFiles = listOf( - "res/drawable/quantum_launchscreen_youtube.xml", - "res/drawable-sw600dp/quantum_launchscreen_youtube.xml" - ) + val splashScreenResourceFiles = + listOf( + "res/drawable/quantum_launchscreen_youtube.xml", + "res/drawable-sw600dp/quantum_launchscreen_youtube.xml", + ) splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile -> - context.xmlEditor[resourceFile].use { - val layerList = it.file.getElementsByTagName("layer-list").item(0) as Element + context.document[resourceFile].use { + val layerList = it.getElementsByTagName("layer-list").item(0) as Element val childNodes = layerList.childNodes for (i in 0 until childNodes.length) { @@ -89,24 +91,24 @@ internal object ThemeResourcePatch : ResourcePatch() { } } } - } private fun addColorResource( context: ResourceContext, resourceFile: String, colorName: String, - colorValue: String + colorValue: String, ) { - context.xmlEditor[resourceFile].use { - val resourcesNode = it.file.getElementsByTagName("resources").item(0) as Element + context.document[resourceFile].use { + val resourcesNode = it.getElementsByTagName("resources").item(0) as Element resourcesNode.appendChild( - it.file.createElement("color").apply { + it.createElement("color").apply { setAttribute("name", colorName) setAttribute("category", "color") textContent = colorValue - }) + }, + ) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt index 6dcc92c7d..4cd94140c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.playercontrols import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.DomFileEditor +import app.revanced.patcher.util.Document import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import java.io.Closeable @@ -18,14 +18,15 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { private var lastLeftOf = "fullscreen_button" private lateinit var resourceContext: ResourceContext - private lateinit var targetXmlEditor: DomFileEditor + private lateinit var targetDocument: Document override fun execute(context: ResourceContext) { resourceContext = context - targetXmlEditor = context.xmlEditor[TARGET_RESOURCE] + targetDocument = context.document[TARGET_RESOURCE] - bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings - .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id + bottomUiContainerResourceId = + ResourceMappingPatch.resourceMappings + .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id } /** @@ -34,18 +35,18 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { * @param resourceDirectoryName The name of the directory containing the hosting resource. */ fun addControls(resourceDirectoryName: String) { - val sourceXmlEditor = resourceContext.xmlEditor[ - this::class.java.classLoader.getResourceAsStream( - "$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME" - )!! - ] + val sourceDocument = + resourceContext.document[ + this::class.java.classLoader.getResourceAsStream( + "$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME", + )!!, + ] val targetElement = "android.support.constraint.ConstraintLayout" - val hostElements = sourceXmlEditor.file.getElementsByTagName(targetElement).item(0).childNodes + val hostElements = sourceDocument.getElementsByTagName(targetElement).item(0).childNodes - val destinationResourceFile = targetXmlEditor.file - val destinationElement = destinationResourceFile.getElementsByTagName(targetElement).item(0) + val destinationElement = targetDocument.getElementsByTagName(targetElement).item(0) for (index in 1 until hostElements.length) { val element = hostElements.item(index).cloneNode(true) @@ -63,11 +64,11 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { lastLeftOf = element.attributes.getNamedItem("android:id").nodeValue.substring(nameSpaceLength) // Add the element. - destinationResourceFile.adoptNode(element) + targetDocument.adoptNode(element) destinationElement.appendChild(element) } - sourceXmlEditor.close() + sourceDocument.close() } - override fun close() = targetXmlEditor.close() + override fun close() = targetDocument.close() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt index b4b50461a..5083cecf5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt @@ -12,12 +12,13 @@ import org.w3c.dom.Element object SettingsResourcePatch : BaseSettingsResourcePatch( IntentPreference( "revanced_settings", - intent = SettingsPatch.newIntent("revanced_settings_intent") + intent = SettingsPatch.newIntent("revanced_settings_intent"), ) to "settings_fragment", - dependencies = setOf( - ResourceMappingPatch::class, - AddResourcesPatch::class, - ) + dependencies = + setOf( + ResourceMappingPatch::class, + AddResourcesPatch::class, + ), ) { // Used for a fingerprint from SettingsPatch. internal var appearanceStringId = -1L @@ -28,12 +29,13 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( AddResourcesPatch(this::class) // Used for a fingerprint from SettingsPatch. - appearanceStringId = ResourceMappingPatch.resourceMappings.find { - it.type == "string" && it.name == "app_theme_appearance_dark" - }!!.id + appearanceStringId = + ResourceMappingPatch.resourceMappings.find { + it.type == "string" && it.name == "app_theme_appearance_dark" + }!!.id arrayOf( - ResourceGroup("layout", "revanced_settings_with_toolbar.xml") + ResourceGroup("layout", "revanced_settings_with_toolbar.xml"), ).forEach { resourceGroup -> context.copyResources("settings", resourceGroup) } @@ -41,20 +43,20 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( // Modify the manifest and add a data intent filter to the LicenseActivity. // Some devices freak out if undeclared data is passed to an intent, // and this change appears to fix the issue. - context.xmlEditor["AndroidManifest.xml"].use { editor -> + context.document["AndroidManifest.xml"].use { document -> // A xml regular-expression would probably work better than this manual searching. - val manifestNodes = editor.file.getElementsByTagName("manifest").item(0).childNodes + val manifestNodes = document.getElementsByTagName("manifest").item(0).childNodes for (i in 0..manifestNodes.length) { val node = manifestNodes.item(i) if (node != null && node.nodeName == "application") { val applicationNodes = node.childNodes for (j in 0..applicationNodes.length) { val applicationChild = applicationNodes.item(j) - if (applicationChild is Element && applicationChild.nodeName == "activity" - && applicationChild.getAttribute("android:name") == "com.google.android.libraries.social.licenses.LicenseActivity" + if (applicationChild is Element && applicationChild.nodeName == "activity" && + applicationChild.getAttribute("android:name") == "com.google.android.libraries.social.licenses.LicenseActivity" ) { - val intentFilter = editor.file.createElement("intent-filter") - val mimeType = editor.file.createElement("data") + val intentFilter = document.createElement("intent-filter") + val mimeType = document.createElement("data") mimeType.setAttribute("android:mimeType", "text/plain") intentFilter.appendChild(mimeType) applicationChild.appendChild(intentFilter) @@ -65,4 +67,4 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( } } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt index 07be6f2eb..bbaf5371e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt @@ -13,20 +13,21 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa dependencies = [CustomPlaybackSpeedPatch::class, RememberPlaybackSpeedPatch::class], compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.48.39", "18.49.37", "19.01.34", "19.02.39", "19.03.35", "19.03.36", - "19.04.37" - ] - ) - ] + "19.04.37", + ], + ), + ], ) @Suppress("unused") -object PlaybackSpeedPatch : BytecodePatch() { +object PlaybackSpeedPatch : BytecodePatch(emptySet()) { override fun execute(context: BytecodeContext) { // All patches this patch depends on succeed. } diff --git a/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/src/main/kotlin/app/revanced/util/ResourceUtils.kt index c5b502cb1..3189f6638 100644 --- a/src/main/kotlin/app/revanced/util/ResourceUtils.kt +++ b/src/main/kotlin/app/revanced/util/ResourceUtils.kt @@ -1,8 +1,8 @@ package app.revanced.util import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.util.Document import app.revanced.patcher.util.DomFileEditor -import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.util.resource.BaseResource import org.w3c.dom.Node import org.w3c.dom.NodeList @@ -25,9 +25,10 @@ fun Node.childElementsSequence() = this.childNodes.asSequence().filter { it.node /** * Performs the given [action] on each child element. */ -fun Node.forEachChildElement(action: (Node) -> Unit) = childElementsSequence().forEach { - action(it) -} +fun Node.forEachChildElement(action: (Node) -> Unit) = + childElementsSequence().forEach { + action(it) + } /** * Recursively traverse the DOM tree starting from the given root node. @@ -45,15 +46,19 @@ fun Node.doRecursively(action: (Node) -> Unit) { * @param sourceResourceDirectory The source resource directory name. * @param resources The resources to copy. */ -fun ResourceContext.copyResources(sourceResourceDirectory: String, vararg resources: ResourceGroup) { - val targetResourceDirectory = this["res"] +fun ResourceContext.copyResources( + sourceResourceDirectory: String, + vararg resources: ResourceGroup, +) { + val targetResourceDirectory = this.get("res", false) for (resourceGroup in resources) { resourceGroup.resources.forEach { resource -> val resourceFile = "${resourceGroup.resourceDirectoryName}/$resource" Files.copy( inputStreamFromBundledResource(sourceResourceDirectory, resourceFile)!!, - targetResourceDirectory.resolve(resourceFile).toPath(), StandardCopyOption.REPLACE_EXISTING + targetResourceDirectory.resolve(resourceFile).toPath(), + StandardCopyOption.REPLACE_EXISTING, ) } } @@ -61,7 +66,7 @@ fun ResourceContext.copyResources(sourceResourceDirectory: String, vararg resour internal fun inputStreamFromBundledResource( sourceResourceDirectory: String, - resourceFile: String + resourceFile: String, ): InputStream? = classLoader.getResourceAsStream("$sourceResourceDirectory/$resourceFile") /** @@ -80,29 +85,29 @@ class ResourceGroup(val resourceDirectoryName: String, vararg val resources: Str fun ResourceContext.iterateXmlNodeChildren( resource: String, targetTag: String, - callback: (node: Node) -> Unit -) = - xmlEditor[classLoader.getResourceAsStream(resource)!!].use { - val stringsNode = it.file.getElementsByTagName(targetTag).item(0).childNodes - for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i)) - } - + callback: (node: Node) -> Unit, +) = document[classLoader.getResourceAsStream(resource)!!].use { + val stringsNode = it.getElementsByTagName(targetTag).item(0).childNodes + for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i)) +} /** - * Copies the specified node of the source [DomFileEditor] to the target [DomFileEditor]. - * @param source the source [DomFileEditor]. - * @param target the target [DomFileEditor]- - * @return AutoCloseable that closes the target [DomFileEditor]s. + * Copies the specified node of the source [Document] to the target [Document]. + * @param source the source [Document]. + * @param target the target [Document]- + * @return AutoCloseable that closes the [Document]s. */ -fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable { - val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes +fun String.copyXmlNode( + source: Document, + target: Document, +): AutoCloseable { + val hostNodes = source.getElementsByTagName(this).item(0).childNodes - val destinationResourceFile = target.file - val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0) + val destinationNode = target.getElementsByTagName(this).item(0) for (index in 0 until hostNodes.length) { val node = hostNodes.item(index).cloneNode(true) - destinationResourceFile.adoptNode(node) + target.adoptNode(node) destinationNode.appendChild(node) } @@ -112,14 +117,30 @@ fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoClosea } } +@Deprecated( + "Use copyXmlNode(Document, Document) instead.", + ReplaceWith( + "this.copyXmlNode(source.file as Document, target.file as Document)", + "app.revanced.patcher.util.Document", + "app.revanced.patcher.util.Document", + ), +) +fun String.copyXmlNode( + source: DomFileEditor, + target: DomFileEditor, +) = this.copyXmlNode(source.file as Document, target.file as Document) + /** * Add a resource node child. * * @param resource The resource to add. * @param resourceCallback Called when a resource has been processed. */ -internal fun Node.addResource(resource: BaseResource, resourceCallback: (BaseResource) -> Unit = { }) { +internal fun Node.addResource( + resource: BaseResource, + resourceCallback: (BaseResource) -> Unit = { }, +) { appendChild(resource.serialize(ownerDocument, resourceCallback)) } -internal fun DomFileEditor?.getNode(tagName: String) = this!!.file.getElementsByTagName(tagName).item(0) \ No newline at end of file +internal fun Document?.getNode(tagName: String) = this!!.getElementsByTagName(tagName).item(0)