Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(YouTube): Support version 19.12, 19.13, 19.14, 19.15 and 19.16 #3239

Merged
merged 13 commits into from
Jun 1, 2024
4 changes: 4 additions & 0 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -1876,7 +1876,11 @@ 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 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;ILkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.Ba
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BuildAuthorizationStringFingerprint
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.GetUserAgentFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference

Expand Down Expand Up @@ -69,7 +69,7 @@ object SpoofClientPatch : BaseSpoofClientPatch(
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
// Replace old.reddit.com with ssl.reddit.com to fix this.
BuildAuthorizationStringFingerprint.result!!.mutableMethod.apply {
val index = indexOfFirstInstruction {
val index = indexOfFirstInstructionOrThrow {
getReference<StringReference>()?.contains("old.reddit.com") == true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnRenderFirstFrameFingerprint
import app.revanced.util.exception
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c

Expand All @@ -34,7 +34,7 @@ object RememberClearDisplayPatch : BytecodePatch(
OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
// region Hook the "Clear display" configuration save event to remember the state of clear display.

val isEnabledIndex = it.indexOfFirstInstruction { opcode == Opcode.IGET_BOOLEAN } + 1
val isEnabledIndex = it.indexOfFirstInstructionOrThrow { opcode == Opcode.IGET_BOOLEAN } + 1
val isEnabledRegister = it.getInstruction<Instruction22c>(isEnabledIndex - 1).registerA

it.addInstructions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import app.revanced.patches.tiktok.misc.integrations.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.SettingsPatch
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
import app.revanced.util.exception
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
Expand Down Expand Up @@ -81,16 +81,16 @@ object DownloadsPatch : BytecodePatch(
},
// Change the download path patch.
DownloadPathParentFingerprint to {
val targetIndex = indexOfFirstInstruction { opcode == Opcode.INVOKE_STATIC }
val targetIndex = indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_STATIC }
val downloadUriMethod = context
.toMethodWalker(this)
.nextMethod(targetIndex, true)
.getMethod() as MutableMethod

val firstIndex = downloadUriMethod.indexOfFirstInstruction {
val firstIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_DIRECT && ((this as Instruction35c).reference as MethodReference).name == "<init>"
}
val secondIndex = downloadUriMethod.indexOfFirstInstruction {
val secondIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType.contains(
"Uri"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFinger
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
import com.android.tools.smali.dexlib2.iface.reference.MethodReference

Expand All @@ -38,7 +39,7 @@ object PlaybackSpeedPatch : BytecodePatch(
SetSpeedFingerprint.result?.let { onVideoSwiped ->
// Remember the playback speed of the current video.
GetSpeedFingerprint.result?.mutableMethod?.apply {
val injectIndex = indexOfFirstInstruction { getReference<MethodReference>()?.returnType == "F" } + 2
val injectIndex = indexOfFirstInstructionOrThrow { getReference<MethodReference>()?.returnType == "F" } + 2
val register = getInstruction<Instruction11x>(injectIndex - 1).registerA

addInstruction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ import app.revanced.util.resultOrThrow
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.08.36",
"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.
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ import app.revanced.util.exception
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
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.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfIdResourceOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference

@Patch(
Expand Down Expand Up @@ -52,6 +53,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.09.38",
"19.10.39",
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand All @@ -60,40 +66,38 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint),
) {

private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/HideAutoplayButtonPatch;"

override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
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 = indexOfIdResourceOrThrow("autonav_preview_stub")

// where to branch away
val branchIndex =
layoutGenMethodInstructions.subList(insertIndex + 1, layoutGenMethodInstructions.size - 1)
.indexOfFirst {
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener"
} + 2

val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction
LayoutConstructorFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = indexOfIdResourceOrThrow("autonav_toggle")
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA

// can be clobbered because this register is overwritten after the injected code
val clobberRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
// Add a conditional branch around the code that inflates and adds the auto repeat button.
val gotoIndex = indexOfFirstInstructionOrThrow(constIndex) {
val parameterTypes = getReference<MethodReference>()?.parameterTypes
opcode == Opcode.INVOKE_VIRTUAL &&
parameterTypes?.size == 2 &&
parameterTypes.first() == "Landroid/view/ViewStub;"
} + 1

addInstructionsWithLabels(
insertIndex,
constIndex,
"""
invoke-static {}, Lapp/revanced/integrations/youtube/patches/HideAutoplayButtonPatch;->isButtonShown()Z
move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideAutoPlayButton()Z
move-result v$constRegister
if-nez v$constRegister, :hidden
""",
ExternalLabel("hidden", jumpInstruction),
ExternalLabel("hidden", getInstruction(gotoIndex)),
)
} ?: throw LayoutConstructorFingerprint.exception
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ import com.android.tools.smali.dexlib2.Opcode
"19.08.36",
"19.09.38",
"19.10.39",
"19.11.43"
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
]
)
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
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.reference.MethodReference
Expand Down Expand Up @@ -56,6 +56,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.09.38",
"19.10.39",
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39",
],
),
],
Expand Down Expand Up @@ -111,7 +116,7 @@ object NavigationButtonsPatch : BytecodePatch(

// Hide navigation button labels.
CreatePivotBarFingerprint.result?.mutableMethod?.apply {
val setTextIndex = indexOfFirstInstruction {
val setTextIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "setText"
}

Expand Down
Loading
Loading