build: Bump dependencies
This commit also migrates away from deprecated to new APIs
This commit is contained in:
@@ -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",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -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",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
+2
-2
@@ -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 }!!
|
||||
|
||||
+5
-5
@@ -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.")
|
||||
}
|
||||
|
||||
+8
-7
@@ -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 ->
|
||||
|
||||
+8
-6
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+28
-19
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-16
@@ -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()
|
||||
}
|
||||
|
||||
+18
-16
@@ -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(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user