mirror of
https://github.com/revanced/revanced-patches
synced 2025-01-11 19:45:50 +01:00
fix: Use deprecated members to ensure backwards compatibility
By migrating to early to new APIs of ReVanced Patcher, if you were to use old versions of ReVanced Patcher, you would get compatibility issues. By using deprecated members until most have updated ReVanced Patcher, we can ensure seamless migration.
This commit is contained in:
parent
930dc297c1
commit
083bd40092
@ -1746,7 +1746,6 @@ public final class app/revanced/util/ResourceUtilsKt {
|
|||||||
public static final fun asSequence (Lorg/w3c/dom/NodeList;)Lkotlin/sequences/Sequence;
|
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 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 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 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 doRecursively (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V
|
||||||
public static final fun forEachChildElement (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V
|
public static final fun forEachChildElement (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
@ -14,7 +14,9 @@ object ExportAllActivitiesPatch : ResourcePatch() {
|
|||||||
private const val EXPORTED_FLAG = "android:exported"
|
private const val EXPORTED_FLAG = "android:exported"
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val activities = document.getElementsByTagName("activity")
|
val activities = document.getElementsByTagName("activity")
|
||||||
|
|
||||||
for (i in 0..activities.length) {
|
for (i in 0..activities.length) {
|
||||||
|
@ -14,7 +14,9 @@ object PredictiveBackGesturePatch : ResourcePatch() {
|
|||||||
private const val FLAG = "android:enableOnBackInvokedCallback"
|
private const val FLAG = "android:enableOnBackInvokedCallback"
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
with(document.getElementsByTagName("application").item(0)) {
|
with(document.getElementsByTagName("application").item(0)) {
|
||||||
if (attributes.getNamedItem(FLAG) != null) return@with
|
if (attributes.getNamedItem(FLAG) != null) return@with
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ import org.w3c.dom.Element
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object EnableAndroidDebuggingPatch : ResourcePatch() {
|
object EnableAndroidDebuggingPatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val applicationNode =
|
val applicationNode =
|
||||||
document
|
document
|
||||||
.getElementsByTagName("application")
|
.getElementsByTagName("application")
|
||||||
|
@ -16,10 +16,12 @@ import java.io.File
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object OverrideCertificatePinningPatch : ResourcePatch() {
|
object OverrideCertificatePinningPatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
val resXmlDirectory = context.get("res/xml", false)
|
val resXmlDirectory = context.get("res/xml")
|
||||||
|
|
||||||
// Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist.
|
// Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist.
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val applicationNode = document.getElementsByTagName("application").item(0) as Element
|
val applicationNode = document.getElementsByTagName("application").item(0) as Element
|
||||||
|
|
||||||
if (!applicationNode.hasAttribute("networkSecurityConfig")) {
|
if (!applicationNode.hasAttribute("networkSecurityConfig")) {
|
||||||
|
@ -52,7 +52,9 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun close() =
|
override fun close() =
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val replacementPackageName = packageNameOption.value
|
val replacementPackageName = packageNameOption.value
|
||||||
|
|
||||||
val manifest = document.getElementsByTagName("manifest").item(0) as Element
|
val manifest = document.getElementsByTagName("manifest").item(0) as Element
|
||||||
|
@ -5,7 +5,7 @@ import app.revanced.patcher.data.ResourceContext
|
|||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.Document
|
import app.revanced.patcher.util.DomFileEditor
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch.resources
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch.resources
|
||||||
import app.revanced.util.*
|
import app.revanced.util.*
|
||||||
import app.revanced.util.resource.ArrayResource
|
import app.revanced.util.resource.ArrayResource
|
||||||
@ -92,8 +92,10 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
|||||||
// instead of overwriting it.
|
// instead of overwriting it.
|
||||||
// This covers the example case such as adding strings and arrays of the same value.
|
// This covers the example case such as adding strings and arrays of the same value.
|
||||||
getOrPut(value, ::mutableMapOf).apply {
|
getOrPut(value, ::mutableMapOf).apply {
|
||||||
context.document[stream].use {
|
context.xmlEditor[stream].use { editor ->
|
||||||
it.getElementsByTagName("app").asSequence().forEach { app ->
|
val document = editor.file
|
||||||
|
|
||||||
|
document.getElementsByTagName("app").asSequence().forEach { app ->
|
||||||
val appId = app.attributes.getNamedItem("id").textContent
|
val appId = app.attributes.getNamedItem("id").textContent
|
||||||
|
|
||||||
getOrPut(appId, ::mutableMapOf).apply {
|
getOrPut(appId, ::mutableMapOf).apply {
|
||||||
@ -237,7 +239,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
|||||||
* This is called after all patches that depend on [AddResourcesPatch] have been executed.
|
* This is called after all patches that depend on [AddResourcesPatch] have been executed.
|
||||||
*/
|
*/
|
||||||
override fun close() {
|
override fun close() {
|
||||||
operator fun MutableMap<String, Pair<Document, Node>>.invoke(
|
operator fun MutableMap<String, Pair<DomFileEditor, Node>>.invoke(
|
||||||
value: Value,
|
value: Value,
|
||||||
resource: BaseResource,
|
resource: BaseResource,
|
||||||
) {
|
) {
|
||||||
@ -253,16 +255,18 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
|||||||
|
|
||||||
getOrPut(resourceFileName) {
|
getOrPut(resourceFileName) {
|
||||||
val targetFile =
|
val targetFile =
|
||||||
context.get("res/$value/$resourceFileName.xml", false).also {
|
context.get("res/$value/$resourceFileName.xml").also {
|
||||||
it.parentFile?.mkdirs()
|
it.parentFile?.mkdirs()
|
||||||
it.createNewFile()
|
it.createNewFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
context.document[targetFile.path].let { document ->
|
context.xmlEditor[targetFile.path].let { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
// Save the target node here as well
|
// Save the target node here as well
|
||||||
// in order to avoid having to call document.getNode("resources")
|
// in order to avoid having to call document.getNode("resources")
|
||||||
// but also save the document so that it can be closed later.
|
// but also save the document so that it can be closed later.
|
||||||
document to document.getNode("resources")
|
editor to document.getNode("resources")
|
||||||
}
|
}
|
||||||
}.let { (_, targetNode) ->
|
}.let { (_, targetNode) ->
|
||||||
targetNode.addResource(resource) { invoke(value, it) }
|
targetNode.addResource(resource) { invoke(value, it) }
|
||||||
@ -276,7 +280,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
|||||||
// This is done to prevent having to open the files for every resource that is added.
|
// 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.
|
// Instead, it is cached once and reused for resources of the same value.
|
||||||
// This map is later accessed to close all documents for the current resource value.
|
// This map is later accessed to close all documents for the current resource value.
|
||||||
val documents = mutableMapOf<String, Pair<Document, Node>>()
|
val documents = mutableMapOf<String, Pair<DomFileEditor, Node>>()
|
||||||
|
|
||||||
resources.forEach { resource -> documents(value, resource) }
|
resources.forEach { resource -> documents(value, resource) }
|
||||||
|
|
||||||
|
@ -8,7 +8,9 @@ import org.w3c.dom.Element
|
|||||||
@Patch(description = "Sets allowAudioPlaybackCapture in manifest to true.")
|
@Patch(description = "Sets allowAudioPlaybackCapture in manifest to true.")
|
||||||
internal object RemoveCaptureRestrictionResourcePatch : ResourcePatch() {
|
internal object RemoveCaptureRestrictionResourcePatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
// get the application node
|
// get the application node
|
||||||
val applicationNode =
|
val applicationNode =
|
||||||
document
|
document
|
||||||
|
@ -15,7 +15,9 @@ import org.w3c.dom.Element
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object RemoveBroadcastsRestrictionPatch : ResourcePatch() {
|
object RemoveBroadcastsRestrictionPatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val applicationNode =
|
val applicationNode =
|
||||||
document
|
document
|
||||||
.getElementsByTagName("application")
|
.getElementsByTagName("application")
|
||||||
|
@ -9,8 +9,10 @@ object HideBannerPatch : ResourcePatch() {
|
|||||||
private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml"
|
private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml"
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document[RESOURCE_FILE_PATH].use {
|
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
|
||||||
it.getElementsByTagName("merge").item(0).childNodes.apply {
|
val document = editor.file
|
||||||
|
|
||||||
|
document.getElementsByTagName("merge").item(0).childNodes.apply {
|
||||||
val attributes = arrayOf("height", "width")
|
val attributes = arrayOf("height", "width")
|
||||||
|
|
||||||
for (i in 1 until length) {
|
for (i in 1 until length) {
|
||||||
|
@ -60,7 +60,9 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
appendChild(child)
|
appendChild(child)
|
||||||
}
|
}
|
||||||
|
|
||||||
document["AndroidManifest.xml"].use { document ->
|
xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val applicationNode =
|
val applicationNode =
|
||||||
document
|
document
|
||||||
.getElementsByTagName("application")
|
.getElementsByTagName("application")
|
||||||
@ -92,8 +94,8 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
private fun ResourceContext.patchManifest() {
|
private fun ResourceContext.patchManifest() {
|
||||||
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName)
|
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName)
|
||||||
|
|
||||||
val manifest = this.get("AndroidManifest.xml", false).readText()
|
val manifest = this.get("AndroidManifest.xml").readText()
|
||||||
this.get("AndroidManifest.xml", false).writeText(
|
this.get("AndroidManifest.xml").writeText(
|
||||||
manifest.replace(
|
manifest.replace(
|
||||||
"package=\"$fromPackageName",
|
"package=\"$fromPackageName",
|
||||||
"package=\"$packageName",
|
"package=\"$packageName",
|
||||||
|
@ -16,14 +16,16 @@ object ResourceMappingPatch : ResourcePatch() {
|
|||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
// save the file in memory to concurrently read from
|
// save the file in memory to concurrently read from
|
||||||
val resourceXmlFile = context.get("res/values/public.xml", false).readBytes()
|
val resourceXmlFile = context.get("res/values/public.xml").readBytes()
|
||||||
|
|
||||||
// create a synchronized list to store the resource mappings
|
// create a synchronized list to store the resource mappings
|
||||||
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
|
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
|
||||||
|
|
||||||
for (threadIndex in 0 until THREAD_COUNT) {
|
for (threadIndex in 0 until THREAD_COUNT) {
|
||||||
threadPoolExecutor.execute thread@{
|
threadPoolExecutor.execute thread@{
|
||||||
context.document[resourceXmlFile.inputStream()].use { document ->
|
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val resources = document.documentElement.childNodes
|
val resources = document.documentElement.childNodes
|
||||||
val resourcesLength = resources.length
|
val resourcesLength = resources.length
|
||||||
val jobSize = resourcesLength / THREAD_COUNT
|
val jobSize = resourcesLength / THREAD_COUNT
|
||||||
|
@ -23,8 +23,8 @@ abstract class BaseSettingsResourcePatch(
|
|||||||
private val rootPreference: Pair<IntentPreference, String>? = null,
|
private val rootPreference: Pair<IntentPreference, String>? = null,
|
||||||
dependencies: Set<PatchClass> = emptySet(),
|
dependencies: Set<PatchClass> = emptySet(),
|
||||||
) : ResourcePatch(
|
) : ResourcePatch(
|
||||||
dependencies = setOf(AddResourcesPatch::class) + dependencies,
|
dependencies = setOf(AddResourcesPatch::class) + dependencies,
|
||||||
),
|
),
|
||||||
MutableSet<BasePreference> by mutableSetOf(),
|
MutableSet<BasePreference> by mutableSetOf(),
|
||||||
Closeable {
|
Closeable {
|
||||||
private lateinit var context: ResourceContext
|
private lateinit var context: ResourceContext
|
||||||
@ -51,13 +51,17 @@ abstract class BaseSettingsResourcePatch(
|
|||||||
|
|
||||||
// Add the root preference to an existing fragment if needed.
|
// Add the root preference to an existing fragment if needed.
|
||||||
rootPreference?.let { (intentPreference, fragment) ->
|
rootPreference?.let { (intentPreference, fragment) ->
|
||||||
context.document["res/xml/$fragment.xml"].use {
|
context.xmlEditor["res/xml/$fragment.xml"].use { editor ->
|
||||||
it.getNode("PreferenceScreen").addPreference(intentPreference)
|
val document = editor.file
|
||||||
|
|
||||||
|
document.getNode("PreferenceScreen").addPreference(intentPreference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all preferences to the ReVanced fragment.
|
// Add all preferences to the ReVanced fragment.
|
||||||
context.document["res/xml/revanced_prefs.xml"].use { document ->
|
context.xmlEditor["res/xml/revanced_prefs.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val revancedPreferenceScreenNode = document.getNode("PreferenceScreen")
|
val revancedPreferenceScreenNode = document.getNode("PreferenceScreen")
|
||||||
forEach { revancedPreferenceScreenNode.addPreference(it) }
|
forEach { revancedPreferenceScreenNode.addPreference(it) }
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ object CustomThemePatch : ResourcePatch() {
|
|||||||
default = "#ff169c46",
|
default = "#ff169c46",
|
||||||
title = "Pressed dark theme accent color",
|
title = "Pressed dark theme accent color",
|
||||||
description =
|
description =
|
||||||
"The color when accented buttons are pressed, by default slightly darker than accent. " +
|
"The color when accented buttons are pressed, by default slightly darker than accent. " +
|
||||||
"Can be a hex color or a resource reference.",
|
"Can be a hex color or a resource reference.",
|
||||||
required = true,
|
required = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,7 +54,9 @@ object CustomThemePatch : ResourcePatch() {
|
|||||||
val accentColor = accentColor!!
|
val accentColor = accentColor!!
|
||||||
val accentColorPressed = accentColorPressed!!
|
val accentColorPressed = accentColorPressed!!
|
||||||
|
|
||||||
context.document["res/values/colors.xml"].use { document ->
|
context.xmlEditor["res/values/colors.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||||
|
|
||||||
for (i in 0 until resourcesNode.childNodes.length) {
|
for (i in 0 until resourcesNode.childNodes.length) {
|
||||||
|
@ -16,7 +16,7 @@ import java.nio.file.Files
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object DynamicColorPatch : ResourcePatch() {
|
object DynamicColorPatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
val resDirectory = context.get("res", false)
|
val resDirectory = context.get("res")
|
||||||
if (!resDirectory.isDirectory) throw PatchException("The res folder can not be found.")
|
if (!resDirectory.isDirectory) throw PatchException("The res folder can not be found.")
|
||||||
|
|
||||||
val valuesV31Directory = resDirectory.resolve("values-v31")
|
val valuesV31Directory = resDirectory.resolve("values-v31")
|
||||||
@ -35,7 +35,9 @@ object DynamicColorPatch : ResourcePatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.document["res/values-v31/colors.xml"].use { document ->
|
context.xmlEditor["res/values-v31/colors.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
mapOf(
|
mapOf(
|
||||||
"ps__twitter_blue" to "@color/twitter_blue",
|
"ps__twitter_blue" to "@color/twitter_blue",
|
||||||
"ps__twitter_blue_pressed" to "@color/twitter_blue_fill_pressed",
|
"ps__twitter_blue_pressed" to "@color/twitter_blue_fill_pressed",
|
||||||
@ -55,7 +57,9 @@ object DynamicColorPatch : ResourcePatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.document["res/values-night-v31/colors.xml"].use { document ->
|
context.xmlEditor["res/values-night-v31/colors.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
mapOf(
|
mapOf(
|
||||||
"twitter_blue" to "@android:color/system_accent1_200",
|
"twitter_blue" to "@android:color/system_accent1_200",
|
||||||
"twitter_blue_fill_pressed" to "@android:color/system_accent1_300",
|
"twitter_blue_fill_pressed" to "@android:color/system_accent1_300",
|
||||||
|
@ -81,7 +81,7 @@ object CustomBrandingPatch : ResourcePatch() {
|
|||||||
}.let { resourceGroups ->
|
}.let { resourceGroups ->
|
||||||
if (icon != REVANCED_ICON) {
|
if (icon != REVANCED_ICON) {
|
||||||
val path = File(icon)
|
val path = File(icon)
|
||||||
val resourceDirectory = context.get("res", false)
|
val resourceDirectory = context.get("res")
|
||||||
|
|
||||||
resourceGroups.forEach { group ->
|
resourceGroups.forEach { group ->
|
||||||
val fromDirectory = path.resolve(group.resourceDirectoryName)
|
val fromDirectory = path.resolve(group.resourceDirectoryName)
|
||||||
@ -102,7 +102,7 @@ object CustomBrandingPatch : ResourcePatch() {
|
|||||||
|
|
||||||
appName?.let { name ->
|
appName?.let { name ->
|
||||||
// Change the app name.
|
// Change the app name.
|
||||||
val manifest = context.get("AndroidManifest.xml", false)
|
val manifest = context.get("AndroidManifest.xml")
|
||||||
manifest.writeText(
|
manifest.writeText(
|
||||||
manifest.readText()
|
manifest.readText()
|
||||||
.replace(
|
.replace(
|
||||||
|
@ -71,7 +71,7 @@ object ChangeHeaderPatch : ResourcePatch() {
|
|||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
// The directories to copy the header to.
|
// The directories to copy the header to.
|
||||||
val targetResourceDirectories = targetResourceDirectoryNames.keys.mapNotNull {
|
val targetResourceDirectories = targetResourceDirectoryNames.keys.mapNotNull {
|
||||||
context.get("res", false).resolve(it).takeIf(File::exists)
|
context.get("res").resolve(it).takeIf(File::exists)
|
||||||
}
|
}
|
||||||
// The files to replace in the target directories.
|
// The files to replace in the target directories.
|
||||||
val targetResourceFiles = targetResourceDirectoryNames.keys.map { directoryName ->
|
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.
|
// For each source folder, copy the files to the target resource directories.
|
||||||
sourceFolders.forEach { dpiSourceFolder ->
|
sourceFolders.forEach { dpiSourceFolder ->
|
||||||
val targetDpiFolder = context.get("res", false).resolve(dpiSourceFolder.name)
|
val targetDpiFolder = context.get("res").resolve(dpiSourceFolder.name)
|
||||||
if (!targetDpiFolder.exists()) return@forEach
|
if (!targetDpiFolder.exists()) return@forEach
|
||||||
|
|
||||||
val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!!
|
val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!!
|
||||||
|
@ -37,7 +37,9 @@ object PlayerControlsBackgroundPatch : ResourcePatch() {
|
|||||||
private const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml"
|
private const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml"
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
context.document[RESOURCE_FILE_PATH].use { document ->
|
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
document.doRecursively node@{ node ->
|
document.doRecursively node@{ node ->
|
||||||
if (node !is Element) return@node
|
if (node !is Element) return@node
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
|
|||||||
findColorResource("inline_time_bar_played_not_highlighted_color")
|
findColorResource("inline_time_bar_played_not_highlighted_color")
|
||||||
|
|
||||||
// Edit the resume playback drawable and replace the progress bar with a custom drawable
|
// Edit the resume playback drawable and replace the progress bar with a custom drawable
|
||||||
context.document["res/drawable/resume_playback_progressbar_drawable.xml"].use { document ->
|
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
||||||
val progressNode = layerList.getElementsByTagName("item").item(1) as Element
|
val progressNode = layerList.getElementsByTagName("item").item(1) as Element
|
||||||
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
|
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
|
||||||
|
@ -65,12 +65,14 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
|
|||||||
)!!
|
)!!
|
||||||
|
|
||||||
var modifiedControlsLayout = false
|
var modifiedControlsLayout = false
|
||||||
val targetDocument = context.document["res/layout/youtube_controls_layout.xml"]
|
val editor = context.xmlEditor["res/layout/youtube_controls_layout.xml"]
|
||||||
"RelativeLayout".copyXmlNode(
|
"RelativeLayout".copyXmlNode(
|
||||||
context.document[hostingResourceStream],
|
context.xmlEditor[hostingResourceStream],
|
||||||
targetDocument,
|
editor,
|
||||||
).also {
|
).also {
|
||||||
val children = targetDocument.getElementsByTagName("RelativeLayout").item(0).childNodes
|
val document = editor.file
|
||||||
|
|
||||||
|
val children = document.getElementsByTagName("RelativeLayout").item(0).childNodes
|
||||||
|
|
||||||
// Replace the startOf with the voting button view so that the button does not overlap
|
// Replace the startOf with the voting button view so that the button does not overlap
|
||||||
for (i in 1 until children.length) {
|
for (i in 1 until children.length) {
|
||||||
@ -82,7 +84,7 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
|
|||||||
view.attributes.getNamedItem(
|
view.attributes.getNamedItem(
|
||||||
"android:id",
|
"android:id",
|
||||||
).nodeValue.endsWith("live_chat_overlay_button")
|
).nodeValue.endsWith("live_chat_overlay_button")
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@ internal object ThemeResourcePatch : ResourcePatch() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Edit theme colors via resources.
|
// Edit theme colors via resources.
|
||||||
context.document["res/values/colors.xml"].use { document ->
|
context.xmlEditor["res/values/colors.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||||
|
|
||||||
val children = resourcesNode.childNodes
|
val children = resourcesNode.childNodes
|
||||||
@ -76,8 +78,10 @@ internal object ThemeResourcePatch : ResourcePatch() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile ->
|
splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile ->
|
||||||
context.document[resourceFile].use {
|
context.xmlEditor[resourceFile].use { editor ->
|
||||||
val layerList = it.getElementsByTagName("layer-list").item(0) as Element
|
val document = editor.file
|
||||||
|
|
||||||
|
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
||||||
|
|
||||||
val childNodes = layerList.childNodes
|
val childNodes = layerList.childNodes
|
||||||
for (i in 0 until childNodes.length) {
|
for (i in 0 until childNodes.length) {
|
||||||
@ -99,11 +103,13 @@ internal object ThemeResourcePatch : ResourcePatch() {
|
|||||||
colorName: String,
|
colorName: String,
|
||||||
colorValue: String,
|
colorValue: String,
|
||||||
) {
|
) {
|
||||||
context.document[resourceFile].use {
|
context.xmlEditor[resourceFile].use { editor ->
|
||||||
val resourcesNode = it.getElementsByTagName("resources").item(0) as Element
|
val document = editor.file
|
||||||
|
|
||||||
|
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
|
||||||
|
|
||||||
resourcesNode.appendChild(
|
resourcesNode.appendChild(
|
||||||
it.createElement("color").apply {
|
document.createElement("color").apply {
|
||||||
setAttribute("name", colorName)
|
setAttribute("name", colorName)
|
||||||
setAttribute("category", "color")
|
setAttribute("category", "color")
|
||||||
textContent = colorValue
|
textContent = colorValue
|
||||||
|
@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.playercontrols
|
|||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.Document
|
import app.revanced.patcher.util.DomFileEditor
|
||||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
|
||||||
@ -18,15 +18,14 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
|
|||||||
private var lastLeftOf = "fullscreen_button"
|
private var lastLeftOf = "fullscreen_button"
|
||||||
|
|
||||||
private lateinit var resourceContext: ResourceContext
|
private lateinit var resourceContext: ResourceContext
|
||||||
private lateinit var targetDocument: Document
|
private lateinit var targetDocumentEditor: DomFileEditor
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
resourceContext = context
|
resourceContext = context
|
||||||
targetDocument = context.document[TARGET_RESOURCE]
|
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
|
||||||
|
|
||||||
bottomUiContainerResourceId =
|
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
|
||||||
ResourceMappingPatch.resourceMappings
|
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
|
||||||
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,21 +34,21 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
|
|||||||
* @param resourceDirectoryName The name of the directory containing the hosting resource.
|
* @param resourceDirectoryName The name of the directory containing the hosting resource.
|
||||||
*/
|
*/
|
||||||
fun addControls(resourceDirectoryName: String) {
|
fun addControls(resourceDirectoryName: String) {
|
||||||
val sourceDocument =
|
val sourceDocumentEditor = resourceContext.xmlEditor[
|
||||||
resourceContext.document[
|
this::class.java.classLoader.getResourceAsStream(
|
||||||
this::class.java.classLoader.getResourceAsStream(
|
"$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME",
|
||||||
"$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME",
|
)!!,
|
||||||
)!!,
|
]
|
||||||
]
|
val sourceDocument = sourceDocumentEditor.file
|
||||||
|
val targetDocument = targetDocumentEditor.file
|
||||||
|
|
||||||
val targetElement = "android.support.constraint.ConstraintLayout"
|
val targetElementTag = "android.support.constraint.ConstraintLayout"
|
||||||
|
|
||||||
val hostElements = sourceDocument.getElementsByTagName(targetElement).item(0).childNodes
|
val sourceElements = sourceDocument.getElementsByTagName(targetElementTag).item(0).childNodes
|
||||||
|
val targetElement = targetDocument.getElementsByTagName(targetElementTag).item(0)
|
||||||
|
|
||||||
val destinationElement = targetDocument.getElementsByTagName(targetElement).item(0)
|
for (index in 1 until sourceElements.length) {
|
||||||
|
val element = sourceElements.item(index).cloneNode(true)
|
||||||
for (index in 1 until hostElements.length) {
|
|
||||||
val element = hostElements.item(index).cloneNode(true)
|
|
||||||
|
|
||||||
// If the element has no attributes there's no point to adding it to the destination.
|
// If the element has no attributes there's no point to adding it to the destination.
|
||||||
if (!element.hasAttributes()) continue
|
if (!element.hasAttributes()) continue
|
||||||
@ -65,10 +64,10 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
|
|||||||
|
|
||||||
// Add the element.
|
// Add the element.
|
||||||
targetDocument.adoptNode(element)
|
targetDocument.adoptNode(element)
|
||||||
destinationElement.appendChild(element)
|
targetElement.appendChild(element)
|
||||||
}
|
}
|
||||||
sourceDocument.close()
|
sourceDocumentEditor.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() = targetDocument.close()
|
override fun close() = targetDocumentEditor.close()
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
|
|||||||
intent = SettingsPatch.newIntent("revanced_settings_intent"),
|
intent = SettingsPatch.newIntent("revanced_settings_intent"),
|
||||||
) to "settings_fragment",
|
) to "settings_fragment",
|
||||||
dependencies =
|
dependencies =
|
||||||
setOf(
|
setOf(
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class,
|
AddResourcesPatch::class,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
// Used for a fingerprint from SettingsPatch.
|
// Used for a fingerprint from SettingsPatch.
|
||||||
internal var appearanceStringId = -1L
|
internal var appearanceStringId = -1L
|
||||||
@ -43,7 +43,9 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
|
|||||||
// Modify the manifest and add a data intent filter to the LicenseActivity.
|
// Modify the manifest and add a data intent filter to the LicenseActivity.
|
||||||
// Some devices freak out if undeclared data is passed to an intent,
|
// Some devices freak out if undeclared data is passed to an intent,
|
||||||
// and this change appears to fix the issue.
|
// and this change appears to fix the issue.
|
||||||
context.document["AndroidManifest.xml"].use { document ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val document = editor.file
|
||||||
|
|
||||||
// A xml regular-expression would probably work better than this manual searching.
|
// A xml regular-expression would probably work better than this manual searching.
|
||||||
val manifestNodes = document.getElementsByTagName("manifest").item(0).childNodes
|
val manifestNodes = document.getElementsByTagName("manifest").item(0).childNodes
|
||||||
for (i in 0..manifestNodes.length) {
|
for (i in 0..manifestNodes.length) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package app.revanced.util
|
package app.revanced.util
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.util.Document
|
|
||||||
import app.revanced.patcher.util.DomFileEditor
|
import app.revanced.patcher.util.DomFileEditor
|
||||||
import app.revanced.util.resource.BaseResource
|
import app.revanced.util.resource.BaseResource
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
@ -50,7 +49,7 @@ fun ResourceContext.copyResources(
|
|||||||
sourceResourceDirectory: String,
|
sourceResourceDirectory: String,
|
||||||
vararg resources: ResourceGroup,
|
vararg resources: ResourceGroup,
|
||||||
) {
|
) {
|
||||||
val targetResourceDirectory = this.get("res", false)
|
val targetResourceDirectory = this.get("res")
|
||||||
|
|
||||||
for (resourceGroup in resources) {
|
for (resourceGroup in resources) {
|
||||||
resourceGroup.resources.forEach { resource ->
|
resourceGroup.resources.forEach { resource ->
|
||||||
@ -86,28 +85,23 @@ fun ResourceContext.iterateXmlNodeChildren(
|
|||||||
resource: String,
|
resource: String,
|
||||||
targetTag: String,
|
targetTag: String,
|
||||||
callback: (node: Node) -> Unit,
|
callback: (node: Node) -> Unit,
|
||||||
) = document[classLoader.getResourceAsStream(resource)!!].use {
|
) = xmlEditor[classLoader.getResourceAsStream(resource)!!].use { editor ->
|
||||||
val stringsNode = it.getElementsByTagName(targetTag).item(0).childNodes
|
val document = editor.file
|
||||||
|
|
||||||
|
val stringsNode = document.getElementsByTagName(targetTag).item(0).childNodes
|
||||||
for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i))
|
for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// TODO: After the migration to the new patcher, remove the following code and replace it with the commented code below.
|
||||||
* Copies the specified node of the source [Document] to the target [Document].
|
fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable {
|
||||||
* @param source the source [Document].
|
val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes
|
||||||
* @param target the target [Document]-
|
|
||||||
* @return AutoCloseable that closes the [Document]s.
|
|
||||||
*/
|
|
||||||
fun String.copyXmlNode(
|
|
||||||
source: Document,
|
|
||||||
target: Document,
|
|
||||||
): AutoCloseable {
|
|
||||||
val hostNodes = source.getElementsByTagName(this).item(0).childNodes
|
|
||||||
|
|
||||||
val destinationNode = target.getElementsByTagName(this).item(0)
|
val destinationResourceFile = target.file
|
||||||
|
val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0)
|
||||||
|
|
||||||
for (index in 0 until hostNodes.length) {
|
for (index in 0 until hostNodes.length) {
|
||||||
val node = hostNodes.item(index).cloneNode(true)
|
val node = hostNodes.item(index).cloneNode(true)
|
||||||
target.adoptNode(node)
|
destinationResourceFile.adoptNode(node)
|
||||||
destinationNode.appendChild(node)
|
destinationNode.appendChild(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,18 +111,44 @@ fun String.copyXmlNode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(
|
// /**
|
||||||
"Use copyXmlNode(Document, Document) instead.",
|
// * Copies the specified node of the source [Document] to the target [Document].
|
||||||
ReplaceWith(
|
// * @param source the source [Document].
|
||||||
"this.copyXmlNode(source.file as Document, target.file as Document)",
|
// * @param target the target [Document]-
|
||||||
"app.revanced.patcher.util.Document",
|
// * @return AutoCloseable that closes the [Document]s.
|
||||||
"app.revanced.patcher.util.Document",
|
// */
|
||||||
),
|
// fun String.copyXmlNode(
|
||||||
)
|
// source: Document,
|
||||||
fun String.copyXmlNode(
|
// target: Document,
|
||||||
source: DomFileEditor,
|
// ): AutoCloseable {
|
||||||
target: DomFileEditor,
|
// val hostNodes = source.getElementsByTagName(this).item(0).childNodes
|
||||||
) = this.copyXmlNode(source.file as Document, target.file as Document)
|
//
|
||||||
|
// val destinationNode = target.getElementsByTagName(this).item(0)
|
||||||
|
//
|
||||||
|
// for (index in 0 until hostNodes.length) {
|
||||||
|
// val node = hostNodes.item(index).cloneNode(true)
|
||||||
|
// target.adoptNode(node)
|
||||||
|
// destinationNode.appendChild(node)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return AutoCloseable {
|
||||||
|
// source.close()
|
||||||
|
// target.close()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @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.
|
* Add a resource node child.
|
||||||
@ -143,4 +163,4 @@ internal fun Node.addResource(
|
|||||||
appendChild(resource.serialize(ownerDocument, resourceCallback))
|
appendChild(resource.serialize(ownerDocument, resourceCallback))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Document?.getNode(tagName: String) = this!!.getElementsByTagName(tagName).item(0)
|
internal fun org.w3c.dom.Document.getNode(tagName: String) = this.getElementsByTagName(tagName).item(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user