Compare commits

..

11 Commits

Author SHA1 Message Date
semantic-release-bot
fb0b3bd673 chore(release): 4.7.0-dev.15 [skip ci]
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)

### Features

* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([96e17cf](96e17cf4de))
2024-04-20 23:17:38 +00:00
LisoUseInAIKyrios
96e17cf4de feat(YouTube): Support version 19.09.38, 19.10.39 and 19.11.43 (#2971)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 01:15:31 +02:00
semantic-release-bot
a7bd0b111e chore(release): 4.7.0-dev.14 [skip ci]
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)

### Features

* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([7ecd992](7ecd992def))
2024-04-20 22:39:55 +00:00
Alberto Ponces
7ecd992def feat(YT Music - Hide 'Get Music Premium' label): Remove occurences of label in settings (#3046)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 00:37:51 +02:00
semantic-release-bot
217d3c69ba chore(release): 4.7.0-dev.13 [skip ci]
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)

### Bug Fixes

* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([e329e1d](e329e1dd1a))
2024-04-18 23:18:22 +00:00
Alberto Ponces
e329e1dd1a fix(YouTube Music - Remove upgrade button): Fix compatibility with latest versions (#3045) 2024-04-19 01:16:25 +02:00
semantic-release-bot
6a8b669ba2 chore(release): 4.7.0-dev.12 [skip ci]
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)

### Features

* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([6fd46ad](6fd46ad9b6))
2024-04-18 22:50:02 +00:00
oSumAtrIX
6fd46ad9b6 feat: Add Hex patch (#3034) 2024-04-18 21:37:46 +02:00
semantic-release-bot
50ddb680ed chore(release): 4.7.0-dev.11 [skip ci]
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)

### Bug Fixes

* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([cc7f79d](cc7f79d903))
2024-04-18 13:21:16 +00:00
LisoUseInAIKyrios
cc7f79d903 fix(YouTube - Spoof device dimensions): Warn about potential performance issues (#3039) 2024-04-18 17:19:04 +04:00
LisoUseInAIKyrios
57274b5435 chore: Fix typo 2024-04-18 12:41:48 +04:00
86 changed files with 675 additions and 295 deletions

View File

@@ -1,3 +1,38 @@
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)
### Features
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)
### Features
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)
### Bug Fixes
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)
### Bug Fixes
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
# [4.7.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.9...v4.7.0-dev.10) (2024-04-17)

View File

@@ -28,6 +28,10 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
public final class app/revanced/patches/all/misc/hex/HexPatch : app/revanced/patches/shared/misc/hex/BaseHexPatch {
public fun <init> ()V
}
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
@@ -669,6 +673,21 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
}
public abstract class app/revanced/patches/shared/misc/hex/BaseHexPatch : app/revanced/patcher/patch/RawResourcePatch {
public fun <init> ()V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement {
public static final field Companion Lapp/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun replacePattern ([B)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion {
}
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public fun <init> (Ljava/util/Set;)V
@@ -705,6 +724,7 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
public final fun get (Ljava/lang/String;Ljava/lang/String;)J
}
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
@@ -1827,11 +1847,12 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
public final class app/revanced/util/BytecodeUtilsKt {
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findIndexForIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.7.0-dev.10
version = 4.7.0-dev.15

View File

@@ -0,0 +1,55 @@
package app.revanced.patches.all.misc.hex
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.registerNewPatchOption
import app.revanced.patches.shared.misc.hex.BaseHexPatch
import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.patcher.patch.Patch as PatchClass
@Patch(
name = "Hex",
description = "Replaces a hexadecimal patterns of bytes of files in an APK.",
use = false,
)
@Suppress("unused")
class HexPatch : BaseHexPatch() {
// TODO: Instead of stringArrayOption, use a custom option type to work around
// https://github.com/ReVanced/revanced-library/issues/48.
// Replace the custom option type with a stringArrayOption once the issue is resolved.
private val replacementsOption by registerNewPatchOption<PatchClass<*>, List<String>>(
key = "replacements",
title = "replacements",
description = """
Hexadecimal patterns to search for and replace with another in a target file.
A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces.
An example pattern is 'aa 01 02 FF'.
Every pattern must be followed by a pipe ('|'), the replacement pattern,
another pipe ('|'), and the path to the file to make the changes in relative to the APK root.
The replacement pattern must have the same length as the original pattern.
Full example of a valid input:
'aa 01 02 FF|00 00 00 00|path/to/file'
""".trimIndentMultiline(),
required = true,
valueType = "StringArray",
)
override val replacements
get() = replacementsOption!!.map { from ->
val (pattern, replacementPattern, targetFilePath) = try {
from.split("|", limit = 3)
} catch (e: Exception) {
throw PatchException(
"Invalid input: $from.\n" +
"Every pattern must be followed by a pipe ('|'), " +
"the replacement pattern, another pipe ('|'), " +
"and the path to the file to make the changes in relative to the APK root. ",
)
}
Replacement(pattern, replacementPattern, targetFilePath)
}
}

View File

@@ -2,23 +2,28 @@ package app.revanced.patches.music.layout.premium
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
name = "Hide 'Get Music Premium' label",
description = "Hides the red \"Get Music Premium\" label from the account menu.",
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint),
setOf(
HideGetPremiumFingerprint,
MembershipSettingsFingerprint,
),
) {
override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let {
@@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
)
}
} ?: throw HideGetPremiumFingerprint.exception
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x0
return-object v0
""",
) ?: throw MembershipSettingsFingerprint.exception
}
}

View File

@@ -12,6 +12,8 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
listOf(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL,
),
listOf("FEmusic_history", "FEmusic_offline"),

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.layout.premium.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object MembershipSettingsFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT
)
)

View File

@@ -13,6 +13,7 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID,
),

View File

@@ -0,0 +1,120 @@
package app.revanced.patches.shared.misc.hex
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.RawResourcePatch
import kotlin.math.max
abstract class BaseHexPatch : RawResourcePatch() {
internal abstract val replacements: List<Replacement>
override fun execute(context: ResourceContext) {
replacements.groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) ->
val targetFile = try {
context[targetFilePath, true]
} catch (e: Exception) {
throw PatchException("Could not find target file: $targetFilePath")
}
// TODO: Use a file channel to read and write the file instead of reading the whole file into memory,
// in order to reduce memory usage.
val targetFileBytes = targetFile.readBytes()
replacements.forEach { replacement ->
replacement.replacePattern(targetFileBytes)
}
targetFile.writeBytes(targetFileBytes)
}
}
/**
* Represents a pattern to search for and its replacement pattern.
*
* @property pattern The pattern to search for.
* @property replacementPattern The pattern to replace the [pattern] with.
* @property targetFilePath The path to the file to make the changes in relative to the APK root.
*/
class Replacement(
private val pattern: String,
replacementPattern: String,
internal val targetFilePath: String,
) {
private val patternBytes = pattern.toByteArrayPattern()
private val replacementPattern = replacementPattern.toByteArrayPattern()
init {
if (this.patternBytes.size != this.replacementPattern.size) {
throw PatchException("Pattern and replacement pattern must have the same length: $pattern")
}
}
/**
* Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes].
*
* @param targetFileBytes The bytes of the file to make the changes in.
*/
fun replacePattern(targetFileBytes: ByteArray) {
val startIndex = indexOfPatternIn(targetFileBytes)
if (startIndex == -1) {
throw PatchException("Pattern not found in target file: $pattern")
}
replacementPattern.copyInto(targetFileBytes, startIndex)
}
// TODO: Allow searching in a file channel instead of a byte array to reduce memory usage.
/**
* Returns the index of the first occurrence of [patternBytes] in the haystack
* using the Boyer-Moore algorithm.
*
* @param haystack The array to search in.
*
* @return The index of the first occurrence of the [patternBytes] in the haystack or -1
* if the [patternBytes] is not found.
*/
private fun indexOfPatternIn(haystack: ByteArray): Int {
val needle = patternBytes
val haystackLength = haystack.size - 1
val needleLength = needle.size - 1
val right = IntArray(256) { -1 }
for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i
var skip: Int
for (i in 0..haystackLength - needleLength) {
skip = 0
for (j in needleLength - 1 downTo 0)
if (needle[j] != haystack[i + j]) {
skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)])
break
}
if (skip == 0) return i
}
return -1
}
companion object {
/**
* Convert a string representing a pattern of hexadecimal bytes to a byte array.
*
* @return The byte array representing the pattern.
* @throws PatchException If the pattern is invalid.
*/
private fun String.toByteArrayPattern() = try {
split(" ").map { it.toInt(16).toByte() }.toByteArray()
} catch (e: NumberFormatException) {
throw PatchException(
"Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " +
"representing hexadecimal bytes separated by spaces",
e,
)
}
}
}
}

View File

@@ -8,19 +8,15 @@ import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement>
private set
private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
override fun execute(context: ResourceContext) {
// save the file in memory to concurrently read from
// sSve the file in memory to concurrently read from it.
val resourceXmlFile = context.get("res/values/public.xml").readBytes()
// create a synchronized list to store the resource mappings
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
@@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1)
element@ for (i in batchStart until batchEnd) {
// make sure to not go out of bounds when rounding errors occur at calculating the jobSize
// Prevent out of bounds.
if (i >= resourcesLength) return@thread
val node = resources.item(i)
@@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
val id = node.getAttribute("id").substring(2).toLong(16)
mappings.add(ResourceElement(typeAttribute, nameAttribute, id))
resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
}
}
}
}
threadPoolExecutor
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
resourceMappings = mappings
threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
}
operator fun get(type: String, name: String) = resourceMappings.first {
it.type == type && it.name == name
}.id
data class ResourceElement(val type: String, val name: String, val id: Long)
}

View File

@@ -11,12 +11,11 @@ object PremiumNavbarTabResourcePatch : ResourcePatch() {
internal var premiumTabId = -1L
override fun execute(context: ResourceContext) {
premiumTabId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "premium_tab"
}.id
premiumTabId = ResourceMappingPatch["id", "premium_tab"]
showBottomNavigationItemsTextId = ResourceMappingPatch.resourceMappings.single {
it.type == "bool" && it.name == "show_bottom_navigation_items_text"
}.id
showBottomNavigationItemsTextId = ResourceMappingPatch[
"bool",
"show_bottom_navigation_items_text",
]
}
}

View File

@@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -14,8 +14,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
LithoFilterPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
object HideAdsResourcePatch : ResourcePatch() {
private const val FILTER_CLASS_DESCRIPTOR =
@@ -35,11 +35,11 @@ object HideAdsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_products_banner"),
SwitchPreference("revanced_hide_shopping_links"),
SwitchPreference("revanced_hide_web_search_results"),
SwitchPreference("revanced_hide_merchandise_banners")
SwitchPreference("revanced_hide_merchandise_banners"),
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id
adAttributionId = ResourceMappingPatch["id", "ad_attribution"]
}
}

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -29,7 +29,9 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.resultOrThrow
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
],

View File

@@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
dependencies = [
IntegrationsPatch::class,
PlayerTypeHookPatch::class,
SwipeControlsResourcePatch::class
SwipeControlsResourcePatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
"19.09.38",
"19.10.39",
"19.11.43", // 19.12.x has an issue with opening YT using external links,
// and the app then crashes if double tap to skip forward/back is immediately used.
// The stack trace shows a call coming from integrations SwipeController,
// but it may be a bug in YT itself as other target versions do not have this issue.
],
),
],
)
@Suppress("unused")
object SwipeControlsBytecodePatch : BytecodePatch(
setOf(
MainActivityFingerprint,
SwipeControlsHostActivityFingerprint
)
SwipeControlsHostActivityFingerprint,
),
) {
override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
@@ -74,9 +79,9 @@ object SwipeControlsBytecodePatch : BytecodePatch(
accessFlags and AccessFlags.FINAL.value.inv(),
annotations,
hiddenApiRestrictions,
implementation
implementation,
).toMutable()
}
}
}
}
}

View File

@@ -40,7 +40,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource
import app.revanced.util.indexOfIdResourceOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
IntegrationsPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
)
@Suppress("unused")
object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint)
setOf(LayoutConstructorFingerprint),
) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button")
SwitchPreference("revanced_hide_autoplay_button"),
)
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions
// resolve the offsets of where to insert the branch instructions and ...
val insertIndex = findIndexForIdResource("autonav_preview_stub")
val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
// where to branch away
val branchIndex =
@@ -90,8 +92,8 @@ object HideAutoplayButtonPatch : BytecodePatch(
move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden
""",
ExternalLabel("hidden", jumpInstruction)
ExternalLabel("hidden", jumpInstruction),
)
} ?: throw LayoutConstructorFingerprint.exception
}
}
}

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -47,7 +47,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37",
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object AlbumCardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards")
SwitchPreference("revanced_hide_album_cards"),
)
albumCardId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "album_card"
}.id
albumCardId = ResourceMappingPatch["layout", "album_card"]
}
}
}

View File

@@ -38,7 +38,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_crowdfunding_box")
SwitchPreference("revanced_hide_crowdfunding_box"),
)
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "donation_companion"
}.id
crowdfundingBoxId = ResourceMappingPatch[
"layout",
"donation_companion",
]
}
}
}

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
@@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards")
SwitchPreference("revanced_hide_endscreen_cards"),
)
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
layoutCircle = findEndscreenResourceId("circle")
layoutIcon = findEndscreenResourceId("icon")
layoutVideo = findEndscreenResourceId("video")
layoutCircle = idOf("circle")
layoutIcon = idOf("icon")
layoutVideo = idOf("video")
}
}
}

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -25,15 +25,12 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
)
)
),
),
)
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout")
filterBarHeightId = "filter_bar_height".layoutResourceId()
barContainerHeightId = "bar_container_height".layoutResourceId()
relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
barContainerHeightId = ResourceMappingPatch["dimen", "bar_container_height"]
}
private fun String.layoutResourceId(type: String = "dimen") =
ResourceMappingPatch.resourceMappings.single { it.type == type && it.name == this }.id
}
}

View File

@@ -34,7 +34,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone
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.patches.all.misc.resources.AddResourcesPatch
@@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
internal var fabButtonId: Long = -1
@@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_floating_microphone_button")
SwitchPreference("revanced_hide_floating_microphone_button"),
)
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id
?: throw PatchException("Can not find required fab button resource id")
fabButtonId = ResourceMappingPatch["id", "fab"]
}
}

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -57,7 +57,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37",
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -5,22 +5,22 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "expand_button_down"
}.id
expandButtonDownId = ResourceMappingPatch[
"layout",
"expand_button_down",
]
}
}
}

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
object HideInfocardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards")
SwitchPreference("revanced_hide_info_cards"),
)
drawerResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "info_cards_drawer_header"
}.id
drawerResourceId = ResourceMappingPatch[
"id",
"info_cards_drawer_header",
]
}
}
}

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.layout.hide.shorts
import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource
import app.revanced.util.injectHideViewCall
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@@ -15,6 +12,9 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.util.exception
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.injectHideViewCall
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@@ -27,11 +27,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class,
HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class,
NavigationBarHookPatch::class
NavigationBarHookPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
@@ -48,10 +49,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
)
@Suppress("unused")
object HideShortsComponentsPatch : BytecodePatch(
@@ -60,8 +63,8 @@ object HideShortsComponentsPatch : BytecodePatch(
ReelConstructorFingerprint,
BottomNavigationBarFingerprint,
RenderBottomNavigationBarParentFingerprint,
SetPivotBarVisibilityParentFingerprint
)
SetPivotBarVisibilityParentFingerprint,
),
) {
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
@@ -79,7 +82,7 @@ object HideShortsComponentsPatch : BytecodePatch(
insertIndex,
viewRegister,
FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf"
"hideShortsShelf",
)
}
} // Do not throw an exception if not resolved.
@@ -93,7 +96,6 @@ object HideShortsComponentsPatch : BytecodePatch(
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: throw CreateShortsButtonsFingerprint.exception
// endregion
// region Hide the Shorts buttons in newer versions of YouTube.
@@ -106,8 +108,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to get the pivotBar view.
SetPivotBarVisibilityParentFingerprint.result?.let {
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef))
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
throw SetPivotBarVisibilityFingerprint.exception
}
SetPivotBarVisibilityFingerprint.result!!.let { result ->
result.mutableMethod.apply {
@@ -116,7 +119,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction(
insertIndex,
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
)
}
}
@@ -124,8 +127,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to hide the navigation bar when Shorts are being played.
RenderBottomNavigationBarParentFingerprint.result?.let {
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef))
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
throw RenderBottomNavigationBarFingerprint.exception
}
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
@@ -142,7 +146,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;"
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
)
}
} ?: throw BottomNavigationBarFingerprint.exception
@@ -150,14 +154,14 @@ object HideShortsComponentsPatch : BytecodePatch(
// endregion
}
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton");
SHARE("reel_dyn_share", "hideShortsShareButton"),
;
fun injectHideCall(method: MutableMethod) {
val referencedIndex = method.findIndexForIdResource(resourceName)
val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
val setIdIndex = referencedIndex + 1
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC

View File

@@ -50,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_navigation_bar"),
)
ResourceMappingPatch.resourceMappings.find {
it.type == "layout" && it.name == "reel_multiple_items_shelf"
}?.also {
reelMultipleItemShelfId = it.id
}
reelPlayerRightCellButtonHeight = ResourceMappingPatch[
"dimen",
"reel_player_right_cell_button_height",
]
reelPlayerRightCellButtonHeight =
ResourceMappingPatch.resourceMappings.single {
it.type == "dimen" && it.name == "reel_player_right_cell_button_height"
}.id
// Resource not present in new versions of the app.
try {
ResourceMappingPatch[
"dimen",
"reel_player_right_cell_button_height",
]
} catch (e: NoSuchElementException) {
return
}.also { reelPlayerRightCellButtonHeight = it }
}
}

View File

@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
// YT 19.12.x moved this code inside another method, and each method has different parameters.
returnType = "V",
parameters = listOf("Z", "Z", "L"),
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
)

View File

@@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen")
SwitchPreference("revanced_disable_suggested_video_end_screen"),
)
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay"
}.id
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
"layout",
"size_adjustable_lite_autonav_overlay",
]
}
}
}

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -30,7 +30,9 @@ import org.w3c.dom.Element
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
)
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
internal var scrimOverlayId = -1L
@@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER)
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
)
scrimOverlayId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "scrim_overlay"
}.id
scrimOverlayId = ResourceMappingPatch[
"id",
"scrim_overlay",
]
}
}

View File

@@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
@Patch(
dependencies = [
SettingsPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
internal var oldUIDislikeId: Long = -1
@@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent")
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
)
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "dislike_button"
}.id
oldUIDislikeId = ResourceMappingPatch[
"id",
"dislike_button",
]
}
}
}

View File

@@ -39,7 +39,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -15,18 +15,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
override fun execute(context: ResourceContext) {
fun findColorResource(resourceName: String): Long {
return ResourceMappingPatch.resourceMappings
.find { it.type == "color" && it.name == resourceName }?.id
?: throw PatchException("Could not find color resource: $resourceName")
}
reelTimeBarPlayedColorId =
findColorResource("reel_time_bar_played_color")
inlineTimeBarColorizedBarPlayedColorDarkId =
findColorResource("inline_time_bar_colorized_bar_played_color_dark")
inlineTimeBarPlayedNotHighlightedColorId =
findColorResource("inline_time_bar_played_not_highlighted_color")
reelTimeBarPlayedColorId = ResourceMappingPatch[
"color",
"reel_time_bar_played_color",
]
inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
"color",
"inline_time_bar_colorized_bar_played_color_dark",
]
inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
"color",
"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 ->
@@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
}
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
val replacementNode =
document.createElement(
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
)
val replacementNode = document.createElement(
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
)
scaleNode.replaceChild(replacementNode, shapeNode)
}
}

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@@ -25,6 +24,7 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.*
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"com.google.android.youtube",
[
"18.48.39",
"18.49.37",
"19.01.34",
@@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
dependencies = [
IntegrationsPatch::class,
@@ -60,8 +63,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
PlayerTypeHookPatch::class,
PlayerControlsBytecodePatch::class,
SponsorBlockResourcePatch::class
]
SponsorBlockResourcePatch::class,
],
)
@Suppress("unused")
object SponsorBlockBytecodePatch : BytecodePatch(
@@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
SeekbarFingerprint,
AppendTimeFingerprint,
LayoutConstructorFingerprint,
AutoRepeatParentFingerprint
)
AutoRepeatParentFingerprint,
),
) {
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
@@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
throw ControlsOverlayFingerprint.exception
}
} ?: throw LayoutConstructorFingerprint.exception
/*
@@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
with(VideoInformationPatch) {
videoTimeHook(
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime"
"setVideoTime",
)
}
@@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction(
moveRectangleToRegisterIndex + 1,
"invoke-static/range {p0 .. p0}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V"
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
)
for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
@@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction(
insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V"
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
)
break
}
@@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
}
seekbarMethod.addInstruction(
i,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
)
break
@@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id
ResourceMappingPatch["id", "controls_layout_stub"]
val zoomOverlayResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id
ResourceMappingPatch["id", "video_zoom_overlay_stub"]
methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!!
@@ -188,7 +192,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"""
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
"""
""",
)
}
@@ -201,7 +205,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"""
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
""".trimIndent()
""".trimIndent(),
)
}
}
@@ -223,7 +227,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"""
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
"""
""",
)
// initialize the player controller
@@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
addInstruction(
startIndex + 3,
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V"
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
)
}
} ?: throw ControlsOverlayFingerprint.exception
} ?: throw ControlsOverlayFingerprint.exception
// get rectangle field name
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
@@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction(
index, "const-string v$register, \"$with\""
index,
"const-string v$register, \"$with\"",
)
}
for ((index, it) in method.implementation!!.instructions.withIndex()) {
@@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
index,
it,
rectangleFieldName
rectangleFieldName,
)
}
}
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
// The vote and create segment buttons automatically change their visibility when appropriate,
// but if buttons are showing when the end of the video is reached then they will not automatically hide.
// Add a hook to forcefully hide when the end of the video is reached.
@@ -283,7 +287,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
}.result?.mutableMethod?.addInstruction(
0,
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V"
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
) ?: throw AutoRepeatFingerprint.exception
// TODO: isSBChannelWhitelisting implementation

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -43,7 +43,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
)
)
]

View File

@@ -12,7 +12,7 @@ internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerpr
opcodes = listOf(
Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT,
null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,

View File

@@ -50,7 +50,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -61,7 +61,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -14,7 +14,7 @@ import app.revanced.util.exception
@Patch(
name = "Spoof device dimensions",
description = "Adds an option to spoof the device dimensions which unlocks higher video qualities if they aren't available on the device.",
description = "Adds an option to spoof the device dimensions which can unlock higher video qualities.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
compatiblePackages = [
CompatiblePackage(
@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -11,8 +11,9 @@ object SpoofSignatureResourcePatch : ResourcePatch() {
internal var scrubbedPreviewThumbnailResourceId: Long = -1
override fun execute(context: ResourceContext) {
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "thumbnail"
}.id
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
"id",
"thumbnail",
]
}
}

View File

@@ -44,7 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37",
"19.09.38",
"19.10.39",
"19.11.43"
),
),
),

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -6,19 +6,14 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
@Patch(
dependencies = [ResourceMappingPatch::class]
dependencies = [ResourceMappingPatch::class],
)
internal object NavigationBarHookResourcePatch : ResourcePatch() {
internal var imageOnlyTabResourceId: Long = -1
internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: ResourceContext) {
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "image_only_tab"
}.id
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
}.id
imageOnlyTabResourceId = ResourceMappingPatch["layout", "image_only_tab"]
actionBarSearchResultsViewMicId = ResourceMappingPatch["layout", "action_bar_search_results_view_mic"]
}
}
}

View File

@@ -24,8 +24,7 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
resourceContext = context
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
bottomUiContainerResourceId = ResourceMappingPatch["id", "bottom_ui_container_stub"]
}
/**

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -31,10 +31,7 @@ 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["string", "app_theme_appearance_dark"]
arrayOf(
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -25,7 +25,9 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],

View File

@@ -8,8 +8,9 @@ internal object CustomPlaybackSpeedResourcePatch : ResourcePatch() {
var speedUnavailableId: Long = -1
override fun execute(context: ResourceContext) {
speedUnavailableId = ResourceMappingPatch.resourceMappings.single {
it.type == "string" && it.name == "varispeed_unavailable_message"
}.id
speedUnavailableId = ResourceMappingPatch[
"string",
"varispeed_unavailable_message",
]
}
}
}

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.video.videoqualitymenu
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.patches.all.misc.resources.AddResourcesPatch
@@ -10,7 +9,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
)
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
internal var videoQualityBottomSheetListFragmentTitle = -1L
@@ -19,13 +18,13 @@ object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_restore_old_video_quality_menu")
SwitchPreference("revanced_restore_old_video_quality_menu"),
)
fun findResource(name: String) = ResourceMappingPatch.resourceMappings.find { it.name == name }?.id
?: throw PatchException("Could not find resource")
// Used for the old type of the video quality menu.
videoQualityBottomSheetListFragmentTitle = findResource("video_quality_bottom_sheet_list_fragment_title")
videoQualityBottomSheetListFragmentTitle = ResourceMappingPatch[
"layout",
"video_quality_bottom_sheet_list_fragment_title",
]
}
}

View File

@@ -15,7 +15,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
/**
@@ -59,24 +58,41 @@ fun MutableMethod.injectHideViewCall(
insertIndex: Int,
viewRegister: Int,
classDescriptor: String,
targetMethod: String
targetMethod: String,
) = addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V",
)
/**
* Find the index of the first instruction with the id of the given resource name.
* Get the index of the first instruction with the id of the given resource name.
*
* Requires [ResourceMappingPatch] as a dependency.
*
* @param resourceName the name of the resource to find the id for.
* @return the index of the first instruction with the id of the given resource name, or -1 if not found.
* @throws PatchException if the resource cannot be found.
* @see [indexOfIdResourceOrThrow]
*/
fun Method.findIndexForIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName
}.id
fun Method.indexOfIdResource(resourceName: String): Int {
val resourceId = ResourceMappingPatch["id", resourceName]
return indexOfFirstWideLiteralInstructionValue(resourceId)
}
return indexOfFirstWideLiteralInstructionValue(getIdResourceId(resourceName))
/**
* Get the index of the first instruction with the id of the given resource name or throw a [PatchException].
*
* Requires [ResourceMappingPatch] as a dependency.
*
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
*/
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
val index = indexOfIdResource(resourceName)
if (index < 0) {
throw PatchException("Found resource id for: '$resourceName' but method does not contain the id: $this")
}
return index
}
/**
@@ -130,27 +146,29 @@ inline fun <reified T : Reference> Instruction.getReference() = (this as? Refere
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
this.implementation!!.instructions.indexOfFirst(predicate)
/**
* Return the resolved methods of [MethodFingerprint]s early.
*/
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint ->
fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) {
'L' -> """
/**
* Return the resolved methods of [MethodFingerprint]s early.
*/
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint ->
fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) {
'L' ->
"""
const/4 v0, $const
return-object v0
"""
'V' -> "return-void"
'I', 'Z' -> """
'V' -> "return-void"
'I', 'Z' ->
"""
const/4 v0, $const
return v0
"""
else -> throw Exception("This case should never happen.")
}
else -> throw Exception("This case should never happen.")
}
result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception
}
result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception
}
}

View File

@@ -98,7 +98,7 @@
<string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string>
<string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string>
<string name="revanced_hide_horizontal_shelves_title">Hide horizontal shelves</string>
<string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it Again</string>
<string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it again</string>
<string name="revanced_hide_horizontal_shelves_summary_off">Shelves are shown</string>
<!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. -->
@@ -1004,8 +1004,9 @@
</patch>
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
<string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed</string>
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nSpoofing the device dimensions can unlock higher video qualities but unknown side effects may occur</string>
<string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed\n\nHigher video qualities might be unlocked but you may experience video playback stuttering, worse battery life, and unknown side effects</string>
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nEnabling this can unlock higher video qualities</string>
<string name="revanced_spoof_device_dimensions_user_dialog_message">Enabling this can cause video playback stuttering, worse battery life, and unknown side effects.</string>
</patch>
<patch id="misc.gms.GmsCoreSupportResourcePatch">
<string name="microg_settings_title">GmsCore Settings</string>