|
| 1 | +package app.revanced.patches.youtube.layout.buttons.overlay |
| 2 | + |
| 3 | +import app.revanced.patcher.data.BytecodeContext |
| 4 | +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction |
| 5 | +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions |
| 6 | +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels |
| 7 | +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction |
| 8 | +import app.revanced.patcher.patch.BytecodePatch |
| 9 | +import app.revanced.patcher.patch.annotation.CompatiblePackage |
| 10 | +import app.revanced.patcher.patch.annotation.Patch |
| 11 | +import app.revanced.patcher.util.smali.ExternalLabel |
| 12 | +import app.revanced.patches.all.misc.resources.AddResourcesPatch |
| 13 | +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference |
| 14 | +import app.revanced.patches.youtube.layout.buttons.overlay.fingerprints.MediaRouteButtonFingerprint |
| 15 | +import app.revanced.patches.youtube.layout.buttons.overlay.fingerprints.PlayerControlsPreviousNextOverlayTouchFingerprint |
| 16 | +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch |
| 17 | +import app.revanced.patches.youtube.misc.settings.SettingsPatch |
| 18 | +import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint |
| 19 | +import app.revanced.patches.youtube.shared.fingerprints.SubtitleButtonControllerFingerprint |
| 20 | +import app.revanced.util.getReference |
| 21 | +import app.revanced.util.indexOfFirstInstructionOrThrow |
| 22 | +import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow |
| 23 | +import app.revanced.util.indexOfIdResourceOrThrow |
| 24 | +import app.revanced.util.resultOrThrow |
| 25 | +import com.android.tools.smali.dexlib2.Opcode |
| 26 | +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction |
| 27 | +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction |
| 28 | +import com.android.tools.smali.dexlib2.iface.reference.MethodReference |
| 29 | + |
| 30 | +@Patch( |
| 31 | + name = "Hide player overlay buttons", |
| 32 | + description = "Adds options to hide the player cast, autoplay, caption button and next/ previous buttons.", |
| 33 | + dependencies = [ |
| 34 | + IntegrationsPatch::class, |
| 35 | + SettingsPatch::class, |
| 36 | + AddResourcesPatch::class, |
| 37 | + HidePlayerOverlayButtonsResourcePatch::class, |
| 38 | + ], |
| 39 | + compatiblePackages = [ |
| 40 | + CompatiblePackage( |
| 41 | + "com.google.android.youtube", |
| 42 | + [ |
| 43 | + "18.38.44", |
| 44 | + "18.49.37", |
| 45 | + "19.16.39", |
| 46 | + "19.25.37", |
| 47 | + "19.34.42", |
| 48 | + ] |
| 49 | + ) |
| 50 | + ] |
| 51 | +) |
| 52 | +@Suppress("unused") |
| 53 | +object HidePlayerOverlayButtonsPatch : BytecodePatch( |
| 54 | + setOf( |
| 55 | + PlayerControlsPreviousNextOverlayTouchFingerprint, |
| 56 | + MediaRouteButtonFingerprint, |
| 57 | + SubtitleButtonControllerFingerprint, |
| 58 | + LayoutConstructorFingerprint |
| 59 | + ) |
| 60 | +) { |
| 61 | + |
| 62 | + private const val INTEGRATIONS_CLASS_DESCRIPTOR = |
| 63 | + "Lapp/revanced/integrations/youtube/patches/HidePlayerOverlayButtonsPatch;" |
| 64 | + |
| 65 | + override fun execute(context: BytecodeContext) { |
| 66 | + AddResourcesPatch(this::class) |
| 67 | + |
| 68 | + SettingsPatch.PreferenceScreen.PLAYER.addPreferences( |
| 69 | + SwitchPreference("revanced_hide_player_previous_next_buttons"), |
| 70 | + SwitchPreference("revanced_hide_cast_button"), |
| 71 | + SwitchPreference("revanced_hide_captions_button"), |
| 72 | + SwitchPreference("revanced_hide_autoplay_button"), |
| 73 | + ) |
| 74 | + |
| 75 | + // region hide player next/previous button |
| 76 | + |
| 77 | + PlayerControlsPreviousNextOverlayTouchFingerprint.resultOrThrow().mutableMethod.apply { |
| 78 | + val resourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow( |
| 79 | + HidePlayerOverlayButtonsResourcePatch.playerControlPreviousButtonTouchArea |
| 80 | + ) |
| 81 | + |
| 82 | + val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) { |
| 83 | + opcode == Opcode.INVOKE_STATIC |
| 84 | + && getReference<MethodReference>()?.parameterTypes?.firstOrNull() == "Landroid/view/View;" |
| 85 | + } |
| 86 | + |
| 87 | + val viewRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC |
| 88 | + |
| 89 | + addInstruction( |
| 90 | + insertIndex, |
| 91 | + "invoke-static { v$viewRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR" + |
| 92 | + "->hidePreviousNextButtons(Landroid/view/View;)V" |
| 93 | + ) |
| 94 | + } |
| 95 | + |
| 96 | + // endregion |
| 97 | + |
| 98 | + // region hide cast button |
| 99 | + |
| 100 | + MediaRouteButtonFingerprint.resultOrThrow().mutableMethod.addInstructions( |
| 101 | + 0, |
| 102 | + """ |
| 103 | + invoke-static { p1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getCastButtonOverrideV2(I)I |
| 104 | + move-result p1 |
| 105 | + """ |
| 106 | + ) |
| 107 | + |
| 108 | + // endregion |
| 109 | + |
| 110 | + // region hide captions button |
| 111 | + |
| 112 | + SubtitleButtonControllerFingerprint.resultOrThrow().mutableMethod.apply { |
| 113 | + // Due to previously applied patches, scanResult index cannot be used in this context |
| 114 | + val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IGET_BOOLEAN) + 1 |
| 115 | + |
| 116 | + addInstruction( |
| 117 | + insertIndex, |
| 118 | + "invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideCaptionsButton(Landroid/widget/ImageView;)V" |
| 119 | + ) |
| 120 | + } |
| 121 | + |
| 122 | + // endregion |
| 123 | + |
| 124 | + // region hide auto play button |
| 125 | + |
| 126 | + LayoutConstructorFingerprint.resultOrThrow().mutableMethod.apply { |
| 127 | + val constIndex = indexOfIdResourceOrThrow("autonav_toggle") |
| 128 | + val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA |
| 129 | + |
| 130 | + // Add a conditional branch around the code that inflates and adds the auto repeat button. |
| 131 | + val gotoIndex = indexOfFirstInstructionOrThrow(constIndex) { |
| 132 | + val parameterTypes = getReference<MethodReference>()?.parameterTypes |
| 133 | + opcode == Opcode.INVOKE_VIRTUAL && |
| 134 | + parameterTypes?.size == 2 && |
| 135 | + parameterTypes.first() == "Landroid/view/ViewStub;" |
| 136 | + } + 1 |
| 137 | + |
| 138 | + addInstructionsWithLabels( |
| 139 | + constIndex, |
| 140 | + """ |
| 141 | + invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideAutoPlayButton()Z |
| 142 | + move-result v$constRegister |
| 143 | + if-nez v$constRegister, :hidden |
| 144 | + """, |
| 145 | + ExternalLabel("hidden", getInstruction(gotoIndex)), |
| 146 | + ) |
| 147 | + } |
| 148 | + |
| 149 | + // endregion |
| 150 | + } |
| 151 | +} |
0 commit comments