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): Merge multiple player overlay patches into Hide player overlay buttons #3800

6 changes: 6 additions & 0 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -1670,6 +1670,12 @@ public final class app/revanced/patches/youtube/layout/buttons/navigation/Naviga
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public final class app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public final class app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.StartVideoInformerFingerprint
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleTrackFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.SubtitleButtonControllerFingerprint
import app.revanced.util.exception


Expand Down
Original file line number Diff line number Diff line change
@@ -1,84 +1,14 @@
package app.revanced.patches.youtube.layout.buttons.autoplay

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
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.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfIdResourceOrThrow
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.reference.MethodReference
import app.revanced.patches.youtube.layout.buttons.overlay.HidePlayerOverlayButtonsPatch

@Patch(
name = "Hide autoplay button",
description = "Adds an option to hide the autoplay button in the video player.",
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
],
),
],
)
@Suppress("unused")
@Deprecated("This patch has been merged into HidePlayerOverlayButtonsPatch.")
object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint),
dependencies = setOf(HidePlayerOverlayButtonsPatch::class),
) {

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.resultOrThrow().mutableMethod.apply {
val constIndex = indexOfIdResourceOrThrow("autonav_toggle")
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).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(
constIndex,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideAutoPlayButton()Z
move-result v$constRegister
if-nez v$constRegister, :hidden
""",
ExternalLabel("hidden", getInstruction(gotoIndex)),
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,61 +1,14 @@
package app.revanced.patches.youtube.layout.buttons.captions

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patches.youtube.layout.buttons.overlay.HidePlayerOverlayButtonsPatch

@Patch(
name = "Hide captions button",
description = "Adds an option to hide the captions button in the video player.",
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
AddResourcesPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
]
)
]
)
@Suppress("unused")
@Deprecated("This patch has been merged into HidePlayerOverlayButtonsPatch.")
object HideCaptionsButtonPatch : BytecodePatch(
setOf(SubtitleButtonControllerFingerprint)
dependencies = setOf(HidePlayerOverlayButtonsPatch::class),
) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_captions_button")
)

val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod

// Due to previously applied patches, scanResult index cannot be used in this context
val insertIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
it.opcode == Opcode.IGET_BOOLEAN
} + 1

subtitleButtonControllerMethod.addInstruction(
insertIndex,
"""
invoke-static {v0}, Lapp/revanced/integrations/youtube/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
"""
)
}
}
Original file line number Diff line number Diff line change
@@ -1,47 +1,14 @@
package app.revanced.patches.youtube.layout.buttons.cast

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
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.layout.buttons.overlay.HidePlayerOverlayButtonsPatch

@Patch(
name = "Hide cast button",
description = "Adds an option to hide the cast button in the video player.",
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage("com.google.android.youtube"),
],
)
object HideCastButtonPatch : BytecodePatch(emptySet()) {
@Suppress("unused")
@Deprecated("This patch has been merged into HidePlayerOverlayButtonsPatch.")
object HideCastButtonPatch : BytecodePatch(
dependencies = setOf(HidePlayerOverlayButtonsPatch::class),
) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_cast_button")
)

val buttonClass = context.findClass("MediaRouteButton")
?: throw PatchException("MediaRouteButton class not found.")

buttonClass.mutableClass.methods.find { it.name == "setVisibility" }?.apply {
addInstructions(
0,
"""
invoke-static {p1}, Lapp/revanced/integrations/youtube/patches/HideCastButtonPatch;->getCastButtonOverrideV2(I)I
move-result p1
""",
)
} ?: throw PatchException("setVisibility method not found.")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package app.revanced.patches.youtube.layout.buttons.overlay

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.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.buttons.overlay.fingerprints.MediaRouteButtonFingerprint
import app.revanced.patches.youtube.layout.buttons.overlay.fingerprints.PlayerControlsPreviousNextOverlayTouchFingerprint
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.patches.youtube.shared.fingerprints.SubtitleButtonControllerFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
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

@Patch(
name = "Hide player overlay buttons",
description = "Adds options to hide the player cast, autoplay, caption button and next/ previous buttons.",
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
HidePlayerOverlayButtonsResourcePatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
]
)
]
)
@Suppress("unused")
object HidePlayerOverlayButtonsPatch : BytecodePatch(
setOf(
PlayerControlsPreviousNextOverlayTouchFingerprint,
MediaRouteButtonFingerprint,
SubtitleButtonControllerFingerprint,
LayoutConstructorFingerprint
)
) {

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

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

SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_player_previous_next_buttons"),
SwitchPreference("revanced_hide_cast_button"),
SwitchPreference("revanced_hide_captions_button"),
SwitchPreference("revanced_hide_autoplay_button"),
)

// region hide player next/previous button

PlayerControlsPreviousNextOverlayTouchFingerprint.resultOrThrow().mutableMethod.apply {
val resourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
HidePlayerOverlayButtonsResourcePatch.playerControlPreviousButtonTouchArea
)

val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
opcode == Opcode.INVOKE_STATIC
&& getReference<MethodReference>()?.parameterTypes?.firstOrNull() == "Landroid/view/View;"
}

val viewRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC

addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR" +
"->hidePreviousNextButtons(Landroid/view/View;)V"
)
}

// endregion

// region hide cast button

MediaRouteButtonFingerprint.resultOrThrow().mutableMethod.addInstructions(
0,
"""
invoke-static { p1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getCastButtonOverrideV2(I)I
move-result p1
"""
)

// endregion

// region hide captions button

SubtitleButtonControllerFingerprint.resultOrThrow().mutableMethod.apply {
// Due to previously applied patches, scanResult index cannot be used in this context
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IGET_BOOLEAN) + 1

addInstruction(
insertIndex,
"invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideCaptionsButton(Landroid/widget/ImageView;)V"
)
}

// endregion

// region hide auto play button

LayoutConstructorFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = indexOfIdResourceOrThrow("autonav_toggle")
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).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(
constIndex,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideAutoPlayButton()Z
move-result v$constRegister
if-nez v$constRegister, :hidden
""",
ExternalLabel("hidden", getInstruction(gotoIndex)),
)
}

// endregion
}
}
Loading
Loading