diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/tabletminiplayer/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/tabletminiplayer/TabletMiniPlayerPatch.kt index 3897272fc..fc064d7f8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/tabletminiplayer/TabletMiniPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/tabletminiplayer/TabletMiniPlayerPatch.kt @@ -14,6 +14,8 @@ import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.Modern import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ModernMiniPlayerForwardButton +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ModernMiniPlayerRewindButton import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YtOutlinePiPWhite import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YtOutlineXWhite import app.revanced.patches.youtube.utils.settings.SettingsPatch @@ -25,6 +27,7 @@ import app.revanced.util.getTargetIndexReversed import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstruction import app.revanced.util.literalInstructionHook +import app.revanced.util.literalInstructionViewHook import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode @@ -93,6 +96,17 @@ object TabletMiniPlayerPatch : BaseBytecodePatch( context.literalInstructionHook(literal, smaliInstruction) } + arrayOf( + ModernMiniPlayerForwardButton, + ModernMiniPlayerRewindButton + ).forEach { literal -> + val smaliInstruction = """ + invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $GENERAL_CLASS_DESCRIPTOR->hideRewindAndForwardButton(Landroid/view/View;)V + """ + + context.literalInstructionViewHook(literal, smaliInstruction) + } + SettingsPatch.addPreference( arrayOf( "SETTINGS: ENABLE_MODERN_MINI_PLAYER" diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt index c4d44f44e..e50d06b37 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt @@ -13,8 +13,9 @@ import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetFooterText import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.literalInstructionHook +import app.revanced.util.literalInstructionViewHook import app.revanced.util.patch.BaseBytecodePatch @Suppress("unused") @@ -45,7 +46,10 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch( CaptionsBottomSheetFingerprint to "hideFooterCaptions", QualityMenuViewInflateFingerprint to "hideFooterQuality" ).map { (fingerprint, name) -> - fingerprint.literalInstructionHook(BottomSheetFooterText, "$PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V") + val smaliInstruction = """ + invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V + """ + fingerprint.literalInstructionViewHook(BottomSheetFooterText, smaliInstruction) } LithoFilterPatch.addFilter(PANELS_FILTER_CLASS_DESCRIPTOR) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index cddb71037..5e3266a3c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -63,6 +63,8 @@ object SharedResourceIdPatch : ResourcePatch() { var InsetOverlayViewLayout = -1L var InterstitialsContainer = -1L var MenuItemView = -1L + var ModernMiniPlayerForwardButton = -1L + var ModernMiniPlayerRewindButton = -1L var MusicAppDeeplinkButtonView = -1L var PanelSubHeader = -1L var PlayerCollapseButton = -1L @@ -147,6 +149,8 @@ object SharedResourceIdPatch : ResourcePatch() { InsetOverlayViewLayout = getId(ID, "inset_overlay_view_layout") InterstitialsContainer = getId(ID, "interstitials_container") MenuItemView = getId(ID, "menu_item_view") + ModernMiniPlayerForwardButton = getId(ID, "modern_miniplayer_forward_button") + ModernMiniPlayerRewindButton = getId(ID, "modern_miniplayer_rewind_button") MusicAppDeeplinkButtonView = getId(ID, "music_app_deeplink_button_view") PanelSubHeader = getId(ID, "panel_subheader") PlayerCollapseButton = getId(ID, "player_collapse_button") diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index ae5d60e6c..7a15e066d 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -139,19 +139,46 @@ fun MethodFingerprint.literalInstructionBooleanHook( } } -fun MethodFingerprint.literalInstructionHook( +fun MethodFingerprint.literalInstructionViewHook( literal: Long, - descriptor: String -) { - resultOrThrow().mutableMethod.apply { - val literalIndex = getWideLiteralInstructionIndex(literal) - val targetIndex = getTargetIndex(literalIndex, Opcode.MOVE_RESULT_OBJECT) - val targetRegister = getInstruction(targetIndex).registerA + smaliInstruction: String +) = resultOrThrow().mutableMethod.literalInstructionViewHook(literal, smaliInstruction) - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $descriptor" - ) +fun MutableMethod.literalInstructionViewHook( + literal: Long, + smaliInstruction: String +) { + val literalIndex = getWideLiteralInstructionIndex(literal) + val targetIndex = getTargetIndex(literalIndex, Opcode.MOVE_RESULT_OBJECT) + val targetRegister = getInstruction(targetIndex).registerA.toString() + + addInstructions( + targetIndex + 1, + smaliInstruction.replace(REGISTER_TEMPLATE_REPLACEMENT, targetRegister) + ) +} + +fun BytecodeContext.literalInstructionViewHook( + literal: Long, + smaliInstruction: String +) { + val context = this + context.classes.forEach { classDef -> + classDef.methods.forEach { method -> + method.implementation.apply { + this?.instructions?.forEachIndexed { _, instruction -> + if (instruction.opcode != Opcode.CONST) + return@forEachIndexed + if ((instruction as Instruction31i).wideLiteral != literal) + return@forEachIndexed + + context.proxy(classDef) + .mutableClass + .findMutableMethodOf(method) + .literalInstructionViewHook(literal, smaliInstruction) + } + } + } } } diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index bda452b63..9ba0d62be 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -280,6 +280,9 @@ Limitations: Enable modern mini player Modern mini player is enabled. Modern mini player is disabled. + Hide rewind & forward button + Buttons are hidden in mini player. + Buttons are shown in mini player. Hide floating microphone button Floating microphone button is hidden. diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 44c157a87..072ffa003 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -172,7 +172,8 @@ + + SETTINGS: ENABLE_MODERN_MINI_PLAYER -->