diff --git a/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt index 1b51409a8..01e0cfa63 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt @@ -11,8 +11,7 @@ object DebuggingPatch : BaseResourcePatch( name = "Enable debug logging", description = "Adds an option to enable debug logging.", dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - use = false + compatiblePackages = COMPATIBLE_PACKAGE ) { override fun execute(context: ResourceContext) { diff --git a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt index 8ce5956fa..ab1beebaa 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt @@ -64,7 +64,7 @@ object PlaybackSpeedFlyoutPanelHookPatch : BytecodePatch( INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR )!!.mutableClass videoUtilsMutableClass.methods.single { method -> - method.name == "showPlaybackSpeedFlyoutPanel" + method.name == "showPlaybackSpeedFlyoutMenu" }.apply { // add playback rate bottom sheet class videoUtilsMutableClass.staticFields.add( diff --git a/src/main/kotlin/app/revanced/patches/shared/elements/StringsElementsUtils.kt b/src/main/kotlin/app/revanced/patches/shared/elements/StringsElementsUtils.kt index 3431d5c8d..b38966a35 100644 --- a/src/main/kotlin/app/revanced/patches/shared/elements/StringsElementsUtils.kt +++ b/src/main/kotlin/app/revanced/patches/shared/elements/StringsElementsUtils.kt @@ -4,6 +4,23 @@ import app.revanced.patcher.data.ResourceContext @Suppress("DEPRECATION") object StringsElementsUtils { + + internal fun ResourceContext.removeStringsElements( + replacements: Array + ) { + var languageList = emptyArray() + val resourceDirectory = this["res"] + val dir = resourceDirectory.listFiles() + for (file in dir!!) { + val path = file.name + if (path.startsWith("values")) { + val targetXml = resourceDirectory.resolve(path).resolve("strings.xml") + if (targetXml.exists()) languageList += path + } + } + removeStringsElements(languageList, replacements) + } + internal fun ResourceContext.removeStringsElements( paths: Array, replacements: Array diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt deleted file mode 100644 index 89a9f33bb..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt +++ /dev/null @@ -1,99 +0,0 @@ -package app.revanced.patches.youtube.ads.fullscreen - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -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.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.ads.fullscreen.fingerprints.InterstitialsContainerFingerprint -import app.revanced.patches.youtube.ads.fullscreen.fingerprints.ShowDialogCommandFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch(dependencies = [SharedResourceIdPatch::class]) -object FullscreenAdsPatch : BytecodePatch( - setOf( - InterstitialsContainerFingerprint, - ShowDialogCommandFingerprint - ) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/AdsFilter;" - - override fun execute(context: BytecodeContext) { - /** - * Hides fullscreen ads - * Non-litho view, used in some old clients. - */ - InterstitialsContainerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2 - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V" - ) - } - } - - /** - * Hides fullscreen ads - * Litho view, used in 'ShowDialogCommandOuterClass' in innertube - */ - ShowDialogCommandFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - // In this method, custom dialog is created and shown. - // There were no issues despite adding “return-void” to the first index. - addInstructionsWithLabels( - 0, - """ - invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - - // If an issue occurs due to patching due to server-side changes in the future, - // Find the instruction whose name is "show" in [MethodReference] and click the 'AlertDialog.BUTTON_POSITIVE' button. - // - // In this case, an instruction for 'getButton' must be added to smali, not in integrations - // (This custom dialog cannot be cast to [AlertDialog] or [Dialog]) - // - // See the comments below. - - // val dialogIndex = getTargetIndexWithMethodReferenceName("show") - // val dialogReference = getInstruction(dialogIndex).reference - // val dialogDefiningClass = (dialogReference as MethodReference).definingClass - // val getButtonMethod = context.findClass(dialogDefiningClass)!! - // .mutableClass.methods.first { method -> - // method.parameters == listOf("I") - // && method.returnType == "Landroid/widget/Button;" - // } - // val getButtonCall = dialogDefiningClass + "->" + getButtonMethod.name + "(I)Landroid/widget/Button;" - // val dialogRegister = getInstruction(dialogIndex).registerC - // val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ) - // val freeRegister = getInstruction(freeIndex).registerA - - // addInstructions( - // dialogIndex + 1, """ - // # Get the 'AlertDialog.BUTTON_POSITIVE' from custom dialog - // # Since this custom dialog cannot be cast to AlertDialog or Dialog, - // # It should come from smali, not integrations. - // const/4 v$freeRegister, -0x1 - // invoke-virtual {v$dialogRegister, $freeRegister}, $getButtonCall - // move-result-object $freeRegister - // invoke-static {$freeRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/Button;)V - // """ - // ) - } - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt index 8bf2bb503..88d889f1e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt @@ -1,20 +1,107 @@ package app.revanced.patches.youtube.ads.general import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +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.Patch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.ads.general.fingerprints.CompactYpcOfferModuleViewFingerprint +import app.revanced.patches.youtube.ads.general.fingerprints.InterstitialsContainerFingerprint +import app.revanced.patches.youtube.ads.general.fingerprints.ShowDialogCommandFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.ADS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AdAttribution +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer import app.revanced.util.findMutableMethodOf +import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.injectHideViewCall +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.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c @Patch(dependencies = [SharedResourceIdPatch::class]) -object GeneralAdsBytecodePatch : BytecodePatch(emptySet()) { +object GeneralAdsBytecodePatch : BytecodePatch( + setOf( + CompactYpcOfferModuleViewFingerprint, + InterstitialsContainerFingerprint, + ShowDialogCommandFingerprint + ) +) { override fun execute(context: BytecodeContext) { + // region patch for hide fullscreen ads + + // non-litho view, used in some old clients. + InterstitialsContainerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2 + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $ADS_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V" + ) + } + } + + // litho view, used in 'ShowDialogCommandOuterClass' in innertube + ShowDialogCommandFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + // In this method, custom dialog is created and shown. + // There were no issues despite adding “return-void” to the first index. + addInstructionsWithLabels( + 0, + """ + invoke-static {}, $ADS_CLASS_DESCRIPTOR->hideFullscreenAds()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + } + + // endregion + + // region patch for hide general ads + + hideAdAttributionView(context) + + // endregion + + // region patch for hide get premium + + CompactYpcOfferModuleViewFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val measuredWidthRegister = + getInstruction(startIndex).registerA + val measuredHeightInstruction = + getInstruction(startIndex + 1) + val measuredHeightRegister = measuredHeightInstruction.registerA + val tempRegister = measuredHeightInstruction.registerB + + addInstructionsWithLabels( + startIndex + 2, """ + invoke-static {}, $ADS_CLASS_DESCRIPTOR->hideGetPremium()Z + move-result v$tempRegister + if-eqz v$tempRegister, :show + const/4 v$measuredWidthRegister, 0x0 + const/4 v$measuredHeightRegister, 0x0 + """, ExternalLabel("show", getInstruction(startIndex + 2)) + ) + } + } + + // endregion + + } + + private fun hideAdAttributionView(context: BytecodeContext) { context.classes.forEach { classDef -> classDef.methods.forEach { method -> method.implementation.apply { @@ -40,7 +127,7 @@ object GeneralAdsBytecodePatch : BytecodePatch(emptySet()) { .injectHideViewCall( insertIndex, viewRegister, - "$COMPONENTS_PATH/AdsFilter;", + ADS_CLASS_DESCRIPTOR, "hideAdAttributionView" ) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt index 770a362eb..88f043f1b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt @@ -2,14 +2,12 @@ package app.revanced.patches.youtube.ads.general import app.revanced.patcher.data.ResourceContext import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.ads.fullscreen.FullscreenAdsPatch -import app.revanced.patches.youtube.ads.getpremium.GetPremiumPatch +import app.revanced.patches.youtube.ads.video.VideoAdsPatch import app.revanced.patches.youtube.utils.fix.doublebacktoclose.DoubleBackToClosePatch import app.revanced.patches.youtube.utils.fix.swiperefresh.SwipeRefreshPatch import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.copyXmlNode import app.revanced.util.doRecursively import app.revanced.util.patch.BaseResourcePatch import app.revanced.util.startsWithAny @@ -17,16 +15,15 @@ import org.w3c.dom.Element @Suppress("DEPRECATION", "unused") object GeneralAdsPatch : BaseResourcePatch( - name = "Hide general ads", - description = "Adds options to hide general ads.", + name = "Hide ads", + description = "Adds options to hide ads.", dependencies = setOf( DoubleBackToClosePatch::class, - FullscreenAdsPatch::class, GeneralAdsBytecodePatch::class, - GetPremiumPatch::class, LithoFilterPatch::class, SettingsPatch::class, - SwipeRefreshPatch::class + SwipeRefreshPatch::class, + VideoAdsPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE ) { @@ -87,24 +84,15 @@ object GeneralAdsPatch : BaseResourcePatch( } } - /** - * Copy arrays - */ - context.copyXmlNode("youtube/doubleback/host", "values/arrays.xml", "resources") - /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: ADS_SETTINGS", - "SETTINGS: HIDE_GENERAL_ADS", - - "SETTINGS: DOUBLE_BACK_TIMEOUT" + "PREFERENCE_SCREEN: ADS" ) ) - SettingsPatch.updatePatchStatus("Hide general ads") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/fingerprints/CompactYpcOfferModuleViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/CompactYpcOfferModuleViewFingerprint.kt similarity index 70% rename from src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/fingerprints/CompactYpcOfferModuleViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/CompactYpcOfferModuleViewFingerprint.kt index a715b09c6..f31490601 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/fingerprints/CompactYpcOfferModuleViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/CompactYpcOfferModuleViewFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.ads.getpremium.fingerprints +package app.revanced.patches.youtube.ads.general.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint @@ -15,5 +15,8 @@ internal object CompactYpcOfferModuleViewFingerprint : MethodFingerprint( Opcode.INVOKE_VIRTUAL, Opcode.RETURN_VOID ), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/CompactYpcOfferModuleView;") && methodDef.name == "onMeasure" } + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/CompactYpcOfferModuleView;") + && methodDef.name == "onMeasure" + } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/InterstitialsContainerFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/InterstitialsContainerFingerprint.kt index 67bc7ad91..92d723356 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/InterstitialsContainerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.ads.fullscreen.fingerprints +package app.revanced.patches.youtube.ads.general.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/ShowDialogCommandFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/ShowDialogCommandFingerprint.kt index aff237c96..2e07fd100 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/fingerprints/ShowDialogCommandFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.ads.fullscreen.fingerprints +package app.revanced.patches.youtube.ads.general.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/GetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/GetPremiumPatch.kt deleted file mode 100644 index 6ee18acb2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/GetPremiumPatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.youtube.ads.getpremium - -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.util.smali.ExternalLabel -import app.revanced.patches.youtube.ads.getpremium.fingerprints.CompactYpcOfferModuleViewFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -object GetPremiumPatch : BytecodePatch( - setOf(CompactYpcOfferModuleViewFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/AdsFilter;" - - override fun execute(context: BytecodeContext) { - - CompactYpcOfferModuleViewFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val measuredWidthRegister = - getInstruction(startIndex).registerA - val measuredHeightInstruction = - getInstruction(startIndex + 1) - val measuredHeightRegister = measuredHeightInstruction.registerA - val tempRegister = measuredHeightInstruction.registerB - - addInstructionsWithLabels( - startIndex + 2, """ - invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideGetPremium()Z - move-result v$tempRegister - if-eqz v$tempRegister, :show - const/4 v$measuredWidthRegister, 0x0 - const/4 v$measuredHeightRegister, 0x0 - """, ExternalLabel("show", getInstruction(startIndex + 2)) - ) - } - } - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsBytecodePatch.kt deleted file mode 100644 index ee93133b3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsBytecodePatch.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.ads.video - -import app.revanced.patches.shared.ads.BaseAdsPatch -import app.revanced.patches.youtube.utils.integrations.Constants.ADS_PATH - -object VideoAdsBytecodePatch : BaseAdsPatch( - "$ADS_PATH/VideoAdsPatch;", - "hideVideoAds" -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt index f5c4eab84..cc563cd9c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt @@ -1,33 +1,9 @@ package app.revanced.patches.youtube.ads.video -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseResourcePatch +import app.revanced.patches.shared.ads.BaseAdsPatch +import app.revanced.patches.youtube.utils.integrations.Constants.ADS_CLASS_DESCRIPTOR -@Suppress("unused") -object VideoAdsPatch : BaseResourcePatch( - name = "Hide video ads", - description = "Adds an option to hide ads in the video player.", - dependencies = setOf( - SettingsPatch::class, - VideoAdsBytecodePatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - override fun execute(context: ResourceContext) { - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: ADS_SETTINGS", - "SETTINGS: HIDE_VIDEO_ADS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide video ads") - - } -} +object VideoAdsPatch : BaseAdsPatch( + ADS_CLASS_DESCRIPTOR, + "hideVideoAds" +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt index 1365ed6d1..5e3aebf43 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt @@ -16,8 +16,6 @@ import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.c import app.revanced.patches.youtube.utils.integrations.Constants.ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts -import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.AccessFlags @@ -149,20 +147,15 @@ object AlternativeThumbnailsPatch : BaseBytecodePatch( ) } - /** - * Copy arrays - */ - contexts.copyXmlNode("youtube/alternativethumbnails/host", "values/arrays.xml", "resources") - /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: ALTERNATIVE_THUMBNAILS_SETTINGS" + "PREFERENCE_SCREEN: ALTERNATIVE_THUMBNAILS" ) ) - SettingsPatch.updatePatchStatus("Alternative thumbnails") + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/BottomPlayerGesturesPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/BottomPlayerGesturesPatch.kt deleted file mode 100644 index 74e68c75e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/BottomPlayerGesturesPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.youtube.buttomplayer.gestures - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.youtube.buttomplayer.gestures.fingerprints.BottomPlayerGesturesFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.BOTTOM_PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object BottomPlayerGesturesPatch : BaseBytecodePatch( - name = "Enable bottom player gestures", - description = "Adds an option to enter fullscreen when swiping down below the video player.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(BottomPlayerGesturesFingerprint) -) { - override fun execute(context: BytecodeContext) { - - BottomPlayerGesturesFingerprint.literalInstructionBooleanHook( - 45372793, - "$BOTTOM_PLAYER_CLASS_DESCRIPTOR->enableBottomPlayerGestures()Z" - ) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: BOTTOM_PLAYER_SETTINGS", - "SETTINGS: ENABLE_BOTTOM_PLAYER_GESTURES" - ) - ) - - SettingsPatch.updatePatchStatus("Enable bottom player gestures") - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/fingerprints/BottomPlayerGesturesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/fingerprints/BottomPlayerGesturesFingerprint.kt deleted file mode 100644 index 57f745b39..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/gestures/fingerprints/BottomPlayerGesturesFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.buttomplayer.gestures.fingerprints - -import app.revanced.util.fingerprint.LiteralValueFingerprint - -internal object BottomPlayerGesturesFingerprint : LiteralValueFingerprint( - returnType = "V", - literalSupplier = { 45372793 } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt new file mode 100644 index 000000000..0bfd95e52 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt @@ -0,0 +1,229 @@ +package app.revanced.patches.youtube.feed.components + +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.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.feed.components.fingerprints.BreakingNewsFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.ChannelListSubMenuFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.DefaultsTabsBarFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.ElementParserFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.ElementParserParentFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.FilterBarHeightFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.LatestVideosButtonFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.RelatedChipCloudFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.SearchResultsChipBarFingerprint +import app.revanced.patches.youtube.feed.components.fingerprints.ShowMoreButtonFingerprint +import app.revanced.patches.youtube.utils.browseid.BrowseIdHookPatch +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.FEED_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TabsBarTextTabView +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.patch.BaseBytecodePatch +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.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +@Suppress("unused") +object FeedComponentsPatch : BaseBytecodePatch( + name = "Hide feed components", + description = "Adds options to hide components related to feed.", + dependencies = setOf( + BrowseIdHookPatch::class, + LithoFilterPatch::class, + NavigationBarHookPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + BreakingNewsFingerprint, + ChannelListSubMenuFingerprint, + DefaultsTabsBarFingerprint, + ElementParserParentFingerprint, + FilterBarHeightFingerprint, + LatestVideosButtonFingerprint, + RelatedChipCloudFingerprint, + SearchResultsChipBarFingerprint, + ShowMoreButtonFingerprint + ) +) { + private const val FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/FeedComponentsFilter;" + private const val FEED_VIDEO_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/FeedVideoFilter;" + private const val KEYWORD_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/KeywordContentFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for hide carousel shelf, subscriptions channel section, latest videos button + + mapOf( + BreakingNewsFingerprint to "hideBreakingNewsShelf", // carousel shelf, only used to tablet layout. + ChannelListSubMenuFingerprint to "hideSubscriptionsChannelSection", // subscriptions channel section + LatestVideosButtonFingerprint to "hideLatestVideosButton", // latest videos button + ).forEach { (fingerprint, methodName) -> + fingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V" + ) + } + } + } + + // endregion + + // region patch for hide category bar + + FilterBarHeightFingerprint.patch { register -> + """ + invoke-static { v$register }, $FEED_CLASS_DESCRIPTOR->hideCategoryBarInFeed(I)I + move-result v$register + """ + } + + RelatedChipCloudFingerprint.patch(1) { register -> + "invoke-static { v$register }, " + + "$FEED_CLASS_DESCRIPTOR->hideCategoryBarInRelatedVideos(Landroid/view/View;)V" + } + + SearchResultsChipBarFingerprint.patch(-1, -2) { register -> + """ + invoke-static { v$register }, $FEED_CLASS_DESCRIPTOR->hideCategoryBarInSearch(I)I + move-result v$register + """ + } + + // endregion + + // region patch for hide channel profile + + DefaultsTabsBarFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val viewIndex = getWideLiteralInstructionIndex(TabsBarTextTabView) + 2 + val viewRegister = getInstruction(viewIndex).registerA + + addInstruction( + viewIndex + 1, + "invoke-static {v$viewRegister}, $FEED_CLASS_DESCRIPTOR->setChannelTabView(Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide mix playlists + + ElementParserFingerprint.resolve( + context, + ElementParserParentFingerprint.resultOrThrow().classDef + ) + ElementParserFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val freeRegister = implementation!!.registerCount - parameters.size - 2 + val insertIndex = indexOfFirstInstruction { + val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference) + + reference?.parameterTypes?.size == 1 + && reference.parameterTypes.first() == "[B" + && reference.returnType.startsWith("L") + } + + val objectIndex = getTargetIndex(Opcode.MOVE_OBJECT) + val objectRegister = getInstruction(objectIndex).registerA + + val jumpIndex = it.scanResult.patternScanResult!!.startIndex + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {v$objectRegister, v$freeRegister}, $FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z + move-result v$freeRegister + if-nez v$freeRegister, :filter + """, ExternalLabel("filter", getInstruction(jumpIndex)) + ) + + addInstruction( + 0, + "move-object/from16 v$freeRegister, p3" + ) + } + } + + // endregion + + // region patch for hide show more button + + ShowMoreButtonFingerprint.resultOrThrow().let { + val getViewMethod = + it.mutableClass.methods.find { method -> + method.parameters.isEmpty() && + method.returnType == "Landroid/view/View;" + } + + getViewMethod?.apply { + val targetIndex = implementation!!.instructions.size - 1 + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex, + "invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->hideShowMoreButton(Landroid/view/View;)V" + ) + } ?: throw PatchException("Failed to find getView method") + } + + // endregion + + LithoFilterPatch.addFilter(FEED_COMPONENTS_FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(FEED_VIDEO_FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_DESCRIPTOR) + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: FEED", + "SETTINGS: HIDE_FEED_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } + + private fun MethodFingerprint.patch( + insertIndexOffset: Int = 0, + hookRegisterOffset: Int = 0, + instructions: (Int) -> String + ) = + resultOrThrow().let { + it.mutableMethod.apply { + val endIndex = it.scanResult.patternScanResult!!.endIndex + + val insertIndex = endIndex + insertIndexOffset + val register = + getInstruction(endIndex + hookRegisterOffset).registerA + + addInstructions(insertIndex, instructions(register)) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/fingerprints/BreakingNewsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/BreakingNewsFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/fingerprints/BreakingNewsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/BreakingNewsFingerprint.kt index e4d839a49..0af30c324 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/fingerprints/BreakingNewsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/BreakingNewsFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.suggestionshelf.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.HorizontalCardList diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/fingerprints/ChannelListSubMenuFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ChannelListSubMenuFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/fingerprints/ChannelListSubMenuFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ChannelListSubMenuFingerprint.kt index bc138d9a8..17fe9b2bd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/fingerprints/ChannelListSubMenuFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ChannelListSubMenuFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.channellistsubmenu.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ChannelListSubMenu import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/fingerprints/DefaultsTabsBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/DefaultsTabsBarFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/fingerprints/DefaultsTabsBarFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/DefaultsTabsBarFingerprint.kt index 022be2a71..3bdfa5a6d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/fingerprints/DefaultsTabsBarFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/DefaultsTabsBarFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.channelprofile.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TabsBarTextTabView import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserFingerprint.kt index 2408736ed..9deebf6aa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.mixplaylists.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserParentFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserParentFingerprint.kt index fdbe0270a..a1e6d83c1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/fingerprints/ElementParserParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ElementParserParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.mixplaylists.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/FilterBarHeightFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/FilterBarHeightFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/FilterBarHeightFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/FilterBarHeightFingerprint.kt index 384756576..bd5cca583 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/FilterBarHeightFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/FilterBarHeightFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.categorybar.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FilterBarHeight diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/fingerprints/LatestVideosButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/LatestVideosButtonFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/fingerprints/LatestVideosButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/LatestVideosButtonFingerprint.kt index 07ee4d7e2..af2c83dda 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/fingerprints/LatestVideosButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/LatestVideosButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.latestvideosbutton.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Bar diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/RelatedChipCloudFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/RelatedChipCloudFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/RelatedChipCloudFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/RelatedChipCloudFingerprint.kt index cf1e83672..7f771088c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/RelatedChipCloudFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/RelatedChipCloudFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.categorybar.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.RelatedChipCloudMargin diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/SearchResultsChipBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/SearchResultsChipBarFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/SearchResultsChipBarFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/SearchResultsChipBarFingerprint.kt index a50b3ca59..a53de7c02 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/fingerprints/SearchResultsChipBarFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/SearchResultsChipBarFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.categorybar.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BarContainerHeight diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/fingerprints/LoadMoreButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ShowMoreButtonFingerprint.kt similarity index 73% rename from src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/fingerprints/LoadMoreButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ShowMoreButtonFingerprint.kt index 7bd5d6344..cae0cf3ae 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/fingerprints/LoadMoreButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/components/fingerprints/ShowMoreButtonFingerprint.kt @@ -1,10 +1,10 @@ -package app.revanced.patches.youtube.general.loadmorebutton.fingerprints +package app.revanced.patches.youtube.feed.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ExpandButtonDown import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.Opcode -internal object LoadMoreButtonFingerprint : LiteralValueFingerprint( +internal object ShowMoreButtonFingerprint : LiteralValueFingerprint( opcodes = listOf( Opcode.CONST, Opcode.CONST_4, diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/FeedFlyoutPanelPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/FeedFlyoutMenuPatch.kt similarity index 76% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/FeedFlyoutPanelPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/FeedFlyoutMenuPatch.kt index 4b7d39d63..007a8b8b4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/FeedFlyoutPanelPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/FeedFlyoutMenuPatch.kt @@ -1,15 +1,15 @@ -package app.revanced.patches.youtube.flyoutpanel.feed +package app.revanced.patches.youtube.feed.flyoutmenu 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.patch.PatchException -import app.revanced.patches.youtube.flyoutpanel.feed.fingerprints.BottomSheetMenuItemBuilderFingerprint -import app.revanced.patches.youtube.flyoutpanel.feed.fingerprints.BottomSheetMenuItemBuilderLegacyFingerprint -import app.revanced.patches.youtube.flyoutpanel.feed.fingerprints.ContextualMenuItemBuilderFingerprint +import app.revanced.patches.youtube.feed.flyoutmenu.fingerprints.BottomSheetMenuItemBuilderFingerprint +import app.revanced.patches.youtube.feed.flyoutmenu.fingerprints.BottomSheetMenuItemBuilderLegacyFingerprint +import app.revanced.patches.youtube.feed.flyoutmenu.fingerprints.ContextualMenuItemBuilderFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FLYOUT_PANEL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.integrations.Constants.FEED_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.patch.BaseBytecodePatch @@ -20,9 +20,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Suppress("unused") -object FeedFlyoutPanelPatch : BaseBytecodePatch( - name = "Hide feed flyout panel", - description = "Adds the ability to hide feed flyout panel components using a custom filter.", +object FeedFlyoutMenuPatch : BaseBytecodePatch( + name = "Hide feed flyout menu", + description = "Adds the ability to hide feed flyout menu components using a custom filter.", dependencies = setOf( SettingsPatch::class, SharedResourceIdPatch::class @@ -54,7 +54,7 @@ object FeedFlyoutPanelPatch : BaseBytecodePatch( addInstructions( targetIndex + 1, """ - invoke-static {v$targetRegister}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->hideFeedFlyoutPanel(Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->hideFlyoutMenu(Ljava/lang/CharSequence;)Ljava/lang/CharSequence; move-result-object v$targetRegister """ ) @@ -77,7 +77,7 @@ object FeedFlyoutPanelPatch : BaseBytecodePatch( addInstruction( targetIndex + 1, "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + - "$FLYOUT_PANEL_CLASS_DESCRIPTOR->hideFeedFlyoutPanel(Landroid/widget/TextView;Ljava/lang/CharSequence;)V" + "$FEED_CLASS_DESCRIPTOR->hideFlyoutMenu(Landroid/widget/TextView;Ljava/lang/CharSequence;)V" ) } } @@ -87,12 +87,11 @@ object FeedFlyoutPanelPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: FLYOUT_PANEL_SETTINGS", - "SETTINGS: HIDE_FEED_FLYOUT_PANEL" + "PREFERENCE_SCREEN: FEED", + "SETTINGS: HIDE_FEED_FLYOUT_MENU" ) ) - SettingsPatch.updatePatchStatus("Hide feed flyout panel") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt index d9d15c7c3..27403e608 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.feed.fingerprints +package app.revanced.patches.youtube.feed.flyoutmenu.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt index 2ba93d8a9..aa96ce7bf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/BottomSheetMenuItemBuilderLegacyFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.feed.fingerprints +package app.revanced.patches.youtube.feed.flyoutmenu.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/ContextualMenuItemBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/ContextualMenuItemBuilderFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/ContextualMenuItemBuilderFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/ContextualMenuItemBuilderFingerprint.kt index 5f1bb6b2a..3e04d7cfc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/feed/fingerprints/ContextualMenuItemBuilderFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/feed/flyoutmenu/fingerprints/ContextualMenuItemBuilderFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.feed.fingerprints +package app.revanced.patches.youtube.feed.flyoutmenu.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.PosterArtWidthDefault diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/oldqualitylayout/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/oldqualitylayout/OldQualityLayoutPatch.kt deleted file mode 100644 index 69cf45c8c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/oldqualitylayout/OldQualityLayoutPatch.kt +++ /dev/null @@ -1,107 +0,0 @@ -package app.revanced.patches.youtube.flyoutpanel.oldqualitylayout - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.utils.fingerprints.QualityMenuViewInflateFingerprint -import app.revanced.patches.youtube.utils.fingerprints.QualitySetterFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.FLYOUT_PANEL_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getReference -import app.revanced.util.getTargetIndex -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.patch.BaseBytecodePatch -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.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference - -@Suppress("unused") -object OldQualityLayoutPatch : BaseBytecodePatch( - name = "Enable old quality layout", - description = "Adds an option to restore the old video quality menu with specific video resolution options.", - dependencies = setOf( - BottomSheetRecyclerViewPatch::class, - LithoFilterPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - QualityMenuViewInflateFingerprint, - QualitySetterFingerprint - ) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/VideoQualityMenuFilter;" - - override fun execute(context: BytecodeContext) { - - /** - * Non-litho view, used in old clients and Shorts. - */ - val videoQualityClass = QualitySetterFingerprint.resultOrThrow().mutableMethod.definingClass - - QualityMenuViewInflateFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex + 1, - "invoke-static { v$insertRegister }, $FLYOUT_PANEL_CLASS_DESCRIPTOR->enableOldQualityMenu(Landroid/widget/ListView;)V" - ) - } - val onItemClickMethod = - it.mutableClass.methods.find { method -> method.name == "onItemClick" } - - onItemClickMethod?.apply { - val insertIndex = getTargetIndex(Opcode.IGET_OBJECT) - val insertRegister = getInstruction(insertIndex).registerA - - val jumpIndex = indexOfFirstInstruction { - opcode == Opcode.IGET_OBJECT - && this.getReference()?.type == videoQualityClass - } - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->enableOldQualityMenu()Z - move-result v$insertRegister - if-nez v$insertRegister, :show - """, ExternalLabel("show", getInstruction(jumpIndex)) - ) - } ?: throw PatchException("Failed to find onItemClick method") - } - - /** - * Litho view - */ - BottomSheetRecyclerViewPatch.injectCall("$FLYOUT_PANEL_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FLYOUT_PANEL_SETTINGS", - "SETTINGS: PLAYER_FLYOUT_PANEL_HEADER", - "SETTINGS: ENABLE_OLD_QUALITY_LAYOUT" - ) - ) - - SettingsPatch.updatePatchStatus("Enable old quality layout") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/autoplaypreview/AutoplayPreviewPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/autoplaypreview/AutoplayPreviewPatch.kt deleted file mode 100644 index 04787b447..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/autoplaypreview/AutoplayPreviewPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.autoplaypreview - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavPreviewStub -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavToggle -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object AutoplayPreviewPatch : BaseBytecodePatch( - name = "Hide autoplay preview", - description = "Adds an option to hide the autoplay preview container when in fullscreen.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(LayoutConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - LayoutConstructorFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val dummyRegister = - getInstruction(getStringInstructionIndex("1.0x")).registerA - val insertIndex = getWideLiteralInstructionIndex(AutoNavPreviewStub) - val jumpIndex = getWideLiteralInstructionIndex(AutoNavToggle) - 1 - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $FULLSCREEN_CLASS_DESCRIPTOR->hideAutoPlayPreview()Z - move-result v$dummyRegister - if-nez v$dummyRegister, :hidden - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: HIDE_AUTOPLAY_PREVIEW" - ) - ) - - SettingsPatch.updatePatchStatus("Hide autoplay preview") - - } -} - diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/compactcontrolsoverlay/CompactControlsOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/compactcontrolsoverlay/CompactControlsOverlayPatch.kt deleted file mode 100644 index a4fab7c9e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/compactcontrolsoverlay/CompactControlsOverlayPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.compactcontrolsoverlay - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getWalkerMethod -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object CompactControlsOverlayPatch : BaseBytecodePatch( - name = "Enable compact controls overlay", - description = "Adds an option to make the fullscreen controls compact.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(YouTubeControlsOverlayFingerprint) -) { - override fun execute(context: BytecodeContext) { - - YouTubeControlsOverlayFingerprint.resultOrThrow().let { - val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex) - walkerMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val targetRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, - """ - invoke-static {v$targetRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->enableCompactControlsOverlay(Z)Z - move-result v$targetRegister - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: FULLSCREEN_EXPERIMENTAL_FLAGS", - "SETTINGS: ENABLE_COMPACT_CONTROLS_OVERLAY" - ) - ) - - SettingsPatch.updatePatchStatus("Enable compact controls overlay") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/EndScreenOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/EndScreenOverlayPatch.kt deleted file mode 100644 index ec3d670fe..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/EndScreenOverlayPatch.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.endscreenoverlay - -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.PatchException -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.fullscreen.endscreenoverlay.fingerprints.EndScreenResultsParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object EndScreenOverlayPatch : BaseBytecodePatch( - name = "Hide end screen overlay", - description = "Adds an option to hide the overlay in fullscreen when swiping up and at the end of videos.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(EndScreenResultsParentFingerprint) -) { - override fun execute(context: BytecodeContext) { - EndScreenResultsParentFingerprint.resultOrThrow().let { - it.mutableClass.methods.find { method -> method.parameters == listOf("I", "Z", "I") } - ?.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $FULLSCREEN_CLASS_DESCRIPTOR->hideEndScreenOverlay()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } ?: throw PatchException("Could not find targetMethod") - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: HIDE_END_SCREEN_OVERLAY" - ) - ) - - SettingsPatch.updatePatchStatus("Hide end screen overlay") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/ForceFullscreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/ForceFullscreenPatch.kt deleted file mode 100644 index 9894a6bc3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/ForceFullscreenPatch.kt +++ /dev/null @@ -1,109 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.forcefullscreen - -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.patch.PatchException -import app.revanced.patches.youtube.fullscreen.forcefullscreen.fingerprints.ClientSettingEndpointFingerprint -import app.revanced.patches.youtube.fullscreen.forcefullscreen.fingerprints.VideoPortraitParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getTargetIndex -import app.revanced.util.patch.BaseBytecodePatch -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.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object ForceFullscreenPatch : BaseBytecodePatch( - name = "Force fullscreen", - description = "Adds an option to forcefully open videos in fullscreen.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - ClientSettingEndpointFingerprint, - VideoPortraitParentFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - /** - * Process that hooks Activity for using {Activity.setRequestedOrientation}. - */ - ClientSettingEndpointFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val getActivityIndex = getStringInstructionIndex("watch") + 2 - val getActivityReference = - getInstruction(getActivityIndex).reference - val classRegister = - getInstruction(getActivityIndex).registerB - - val watchDescriptorMethodIndex = - getStringInstructionIndex("start_watch_minimized") - 1 - val watchDescriptorRegister = - getInstruction(watchDescriptorMethodIndex).registerD - - addInstructions( - watchDescriptorMethodIndex, """ - invoke-static {v$watchDescriptorRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->forceFullscreen(Z)Z - move-result v$watchDescriptorRegister - """ - ) - - val insertIndex = getStringInstructionIndex("force_fullscreen") - val freeRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - iget-object v$freeRegister, v$classRegister, $getActivityReference - check-cast v$freeRegister, Landroid/app/Activity; - sput-object v$freeRegister, $FULLSCREEN_CLASS_DESCRIPTOR->watchDescriptorActivity:Landroid/app/Activity; - """ - ) - } - } - - /** - * Don't rotate the screen in vertical video. - * Add an instruction to check the vertical video. - */ - VideoPortraitParentFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val stringIndex = - getStringInstructionIndex("Acquiring NetLatencyActionLogger failed. taskId=") - val invokeIndex = getTargetIndex(stringIndex, Opcode.INVOKE_INTERFACE) - val targetIndex = getTargetIndex(invokeIndex, Opcode.CHECK_CAST) - val targetClass = context - .findClass(getInstruction(targetIndex).reference.toString())!! - .mutableClass - - targetClass.methods.find { method -> method.parameters == listOf("I", "I", "Z") } - ?.apply { - addInstruction( - 1, - "invoke-static {p1, p2}, $FULLSCREEN_CLASS_DESCRIPTOR->setVideoPortrait(II)V" - ) - } ?: throw PatchException("Could not find targetMethod") - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: FULLSCREEN_EXPERIMENTAL_FLAGS", - "SETTINGS: FORCE_FULLSCREEN" - ) - ) - - SettingsPatch.updatePatchStatus("Force fullscreen") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/FullscreenPanelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/FullscreenPanelsPatch.kt deleted file mode 100644 index e17f6f426..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/FullscreenPanelsPatch.kt +++ /dev/null @@ -1,81 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.fullscreenpanels - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.fullscreen.fullscreenpanels.fingerprints.FullscreenEngagementPanelFingerprint -import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.quickactions.QuickActionsHookPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenEngagementPanel -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object FullscreenPanelsPatch : BaseBytecodePatch( - name = "Hide fullscreen panels", - description = "Adds an option to hide panels such as live chat when in fullscreen.", - dependencies = setOf( - QuickActionsHookPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - FullscreenEngagementPanelFingerprint, - LayoutConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - FullscreenEngagementPanelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val literalIndex = getWideLiteralInstructionIndex(FullScreenEngagementPanel) - val targetIndex = getTargetIndex(literalIndex, Opcode.CHECK_CAST) - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->hideFullscreenPanels(Landroidx/coordinatorlayout/widget/CoordinatorLayout;)V" - ) - } - } - - LayoutConstructorFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val dummyIndex = getWideLiteralInstructionIndex(159962) - val dummyRegister = getInstruction(dummyIndex).registerA - val addViewIndex = getTargetIndexWithMethodReferenceName("addView") - - addInstructionsWithLabels( - addViewIndex, """ - invoke-static {}, $FULLSCREEN_CLASS_DESCRIPTOR->showFullscreenTitle()Z - move-result v$dummyRegister - if-eqz v$dummyRegister, :hidden - """, ExternalLabel("hidden", getInstruction(addViewIndex + 1)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: HIDE_FULLSCREEN_PANELS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide fullscreen panels") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/LandScapeModePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/LandScapeModePatch.kt deleted file mode 100644 index e56ef8f24..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/LandScapeModePatch.kt +++ /dev/null @@ -1,111 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode - -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.patches.youtube.fullscreen.landscapemode.fingerprints.BroadcastReceiverFingerprint -import app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints.LandScapeModeConfigFingerprint -import app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints.OrientationParentFingerprint -import app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints.OrientationPrimaryFingerprint -import app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints.OrientationSecondaryFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getTargetIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object LandScapeModePatch : BaseBytecodePatch( - name = "Landscape mode", - description = "Adds an option to disable landscape mode when entering fullscreen" + - "and an option to keep landscape mode when turning the screen off and on in fullscreen.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - BroadcastReceiverFingerprint, - LandScapeModeConfigFingerprint, - OrientationParentFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - /** - * Disable landscape mode - */ - OrientationParentFingerprint.resultOrThrow().classDef.let { classDef -> - arrayOf( - OrientationPrimaryFingerprint, - OrientationSecondaryFingerprint - ).forEach { fingerprint -> - fingerprint.resolve(context, classDef) - - fingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val index = it.scanResult.patternScanResult!!.endIndex - val register = getInstruction(index).registerA - - addInstructions( - index + 1, """ - invoke-static {v$register}, $FULLSCREEN_CLASS_DESCRIPTOR->disableLandScapeMode(Z)Z - move-result v$register - """ - ) - } - } - } - } - - /** - * Keep landscape mode - */ - LandScapeModeConfigFingerprint.result?.let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->keepFullscreen(Z)Z - move-result v$insertRegister - """ - ) - } - - BroadcastReceiverFingerprint.resultOrThrow().let { result -> - result.mutableMethod.apply { - val stringIndex = getStringInstructionIndex("android.intent.action.SCREEN_ON") - val insertIndex = getTargetIndex(stringIndex, Opcode.IF_EQZ) + 1 - - addInstruction( - insertIndex, - "invoke-static {}, $FULLSCREEN_CLASS_DESCRIPTOR->setScreenStatus()V" - ) - } - } - - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: KEEP_LANDSCAPE_MODE" - ) - ) - } // no exceptions are raised for compatibility with all versions. - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: FULLSCREEN_EXPERIMENTAL_FLAGS", - "SETTINGS: DISABLE_LANDSCAPE_MODE" - ) - ) - - SettingsPatch.updatePatchStatus("Landscape mode") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/quickactions/QuickActionsComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/fullscreen/quickactions/QuickActionsComponentsPatch.kt deleted file mode 100644 index b3310ba75..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/quickactions/QuickActionsComponentsPatch.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.youtube.fullscreen.quickactions - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.quickactions.QuickActionsHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object QuickActionsComponentsPatch : BaseBytecodePatch( - name = "Quick actions components", - description = "Adds options to hide and customize components below the seekbar in fullscreen.", - dependencies = setOf( - LithoFilterPatch::class, - QuickActionsHookPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/QuickActionFilter;" - - override fun execute(context: BytecodeContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - QuickActionsHookPatch.injectQuickActionMargin() - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: BOTTOM_PLAYER_SETTINGS", - "SETTINGS: QUICK_ACTIONS_COMPONENTS" - ) - ) - - SettingsPatch.updatePatchStatus("Quick actions components") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/AccountMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/AccountMenuPatch.kt deleted file mode 100644 index 485c9cba8..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/AccountMenuPatch.kt +++ /dev/null @@ -1,102 +0,0 @@ -package app.revanced.patches.youtube.general.accountmenu - -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.patches.youtube.general.accountmenu.fingerprints.AccountListFingerprint -import app.revanced.patches.youtube.general.accountmenu.fingerprints.AccountListParentFingerprint -import app.revanced.patches.youtube.general.accountmenu.fingerprints.AccountMenuFingerprint -import app.revanced.patches.youtube.general.accountmenu.fingerprints.AccountMenuParentFingerprint -import app.revanced.patches.youtube.general.accountmenu.fingerprints.AccountMenuPatchFingerprint -import app.revanced.patches.youtube.general.accountmenu.fingerprints.SetViewGroupMarginFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction - -@Suppress("unused") -object AccountMenuPatch : BaseBytecodePatch( - name = "Hide account menu", - description = "Adds the ability to hide account menu elements using a custom filter in the account menu and You tab.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - AccountListParentFingerprint, - AccountMenuParentFingerprint, - AccountMenuPatchFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - AccountListParentFingerprint.resultOrThrow().let { parentResult -> - AccountListFingerprint.resolve(context, parentResult.classDef) - - AccountListFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex + 3 - val targetInstruction = getInstruction(targetIndex) - - addInstruction( - targetIndex, - "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + - "$GENERAL_CLASS_DESCRIPTOR->hideAccountList(Landroid/view/View;Ljava/lang/CharSequence;)V" - ) - } - } - } - - AccountMenuParentFingerprint.resultOrThrow().let { parentResult -> - AccountMenuFingerprint.resolve(context, parentResult.classDef) - SetViewGroupMarginFingerprint.resolve(context, parentResult.classDef) - - AccountMenuFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex + 2 - val targetInstruction = getInstruction(targetIndex) - - addInstruction( - targetIndex, - "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + - "$GENERAL_CLASS_DESCRIPTOR->hideAccountMenu(Landroid/view/View;Ljava/lang/CharSequence;)V" - ) - } - } - - SetViewGroupMarginFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val setViewGroupMarginIndex = it.scanResult.patternScanResult!!.startIndex - val setViewGroupMarginReference = - getInstruction(setViewGroupMarginIndex).reference - - AccountMenuPatchFingerprint.resultOrThrow().mutableMethod.addInstructions( - 0, """ - const/4 v0, 0x0 - invoke-static {p0, v0, v0}, $setViewGroupMarginReference - """ - ) - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_ACCOUNT_MENU" - ) - ) - - SettingsPatch.updatePatchStatus("Hide account menu") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuPatchFingerprint.kt deleted file mode 100644 index b6bc7a4fb..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuPatchFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import com.android.tools.smali.dexlib2.AccessFlags - -internal object AccountMenuPatchFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, - customFingerprint = { methodDef, _ -> - methodDef.definingClass == GENERAL_CLASS_DESCRIPTOR - && methodDef.name == "hideAccountMenu" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsPatch.kt index 0e3c55475..99832508c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsPatch.kt @@ -32,7 +32,6 @@ object AutoCaptionsPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Disable auto captions") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/PlayerPopupPanelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/PlayerPopupPanelsPatch.kt deleted file mode 100644 index 0a3d60cf9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/PlayerPopupPanelsPatch.kt +++ /dev/null @@ -1,53 +0,0 @@ -package app.revanced.patches.youtube.general.autopopuppanels - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.general.autopopuppanels.fingerprints.EngagementPanelControllerFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object PlayerPopupPanelsPatch : BaseBytecodePatch( - name = "Hide auto player popup panels", - description = "Adds an option to hide panels (such as live chat) from opening automatically.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(EngagementPanelControllerFingerprint) -) { - override fun execute(context: BytecodeContext) { - - EngagementPanelControllerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideAutoPlayerPopupPanels()Z - move-result v0 - if-eqz v0, :shown - # The type of the fourth parameter is boolean. - if-eqz p4, :shown - const/4 v0, 0x0 - return-object v0 - """, ExternalLabel("shown", getInstruction(0)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_AUTO_PLAYER_POPUP_PANELS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide auto player popup panels") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/CastButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/CastButtonPatch.kt deleted file mode 100644 index cfa3f6b22..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/CastButtonPatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.youtube.general.castbutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patches.youtube.general.castbutton.fingerprints.CastButtonFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object CastButtonPatch : BaseBytecodePatch( - name = "Hide cast button", - description = "Adds an option to hide the cast button.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(CastButtonFingerprint) -) { - override fun execute(context: BytecodeContext) { - CastButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructions( - 0, """ - invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I - move-result p1 - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_CAST_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide cast button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/fingerprints/CastButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/fingerprints/CastButtonFingerprint.kt deleted file mode 100644 index a30f5bbe9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/castbutton/fingerprints/CastButtonFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.general.castbutton.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -internal object CastButtonFingerprint : MethodFingerprint( - parameters = listOf("I"), - customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("/MediaRouteButton;") - && methodDef.name == "setVisibility" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/CategoryBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/CategoryBarPatch.kt deleted file mode 100644 index f1afea80a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/categorybar/CategoryBarPatch.kt +++ /dev/null @@ -1,85 +0,0 @@ -package app.revanced.patches.youtube.general.categorybar - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.general.categorybar.fingerprints.FilterBarHeightFingerprint -import app.revanced.patches.youtube.general.categorybar.fingerprints.RelatedChipCloudFingerprint -import app.revanced.patches.youtube.general.categorybar.fingerprints.SearchResultsChipBarFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object CategoryBarPatch : BaseBytecodePatch( - name = "Hide category bar", - description = "Adds an option to hide the category bar in feeds.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - FilterBarHeightFingerprint, - RelatedChipCloudFingerprint, - SearchResultsChipBarFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - FilterBarHeightFingerprint.patch { register -> - """ - invoke-static { v$register }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBarInFeed(I)I - move-result v$register - """ - } - - RelatedChipCloudFingerprint.patch(1) { register -> - "invoke-static { v$register }, " + - "$GENERAL_CLASS_DESCRIPTOR->hideCategoryBarInRelatedVideo(Landroid/view/View;)V" - } - - SearchResultsChipBarFingerprint.patch(-1, -2) { register -> - """ - invoke-static { v$register }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBarInSearchResults(I)I - move-result v$register - """ - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_CATEGORY_BAR" - ) - ) - - SettingsPatch.updatePatchStatus("Hide category bar") - - } - - private fun MethodFingerprint.patch( - insertIndexOffset: Int = 0, - hookRegisterOffset: Int = 0, - instructions: (Int) -> String - ) = - resultOrThrow().let { - it.mutableMethod.apply { - val endIndex = it.scanResult.patternScanResult!!.endIndex - - val insertIndex = endIndex + insertIndexOffset - val register = - getInstruction(endIndex + hookRegisterOffset).registerA - - addInstructions(insertIndex, instructions(register)) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/ChannelListSubMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/ChannelListSubMenuPatch.kt deleted file mode 100644 index b4b293f59..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/channellistsubmenu/ChannelListSubMenuPatch.kt +++ /dev/null @@ -1,60 +0,0 @@ -package app.revanced.patches.youtube.general.channellistsubmenu - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.channellistsubmenu.fingerprints.ChannelListSubMenuFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object ChannelListSubMenuPatch : BaseBytecodePatch( - name = "Hide channel avatar section", - description = "Adds an option to hide the channel avatar section of the subscription feed.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(ChannelListSubMenuFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ChannelListSubMenuFilter;" - - override fun execute(context: BytecodeContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - ChannelListSubMenuFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val endIndex = it.scanResult.patternScanResult!!.endIndex - val register = getInstruction(endIndex).registerA - - addInstruction( - endIndex + 1, - "invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->hideChannelListSubMenu(Landroid/view/View;)V" - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_CHANNEL_LIST_SUBMENU" - ) - ) - - SettingsPatch.updatePatchStatus("Hide channel avatar section") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt new file mode 100644 index 000000000..7fcd0333c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt @@ -0,0 +1,246 @@ +package app.revanced.patches.youtube.general.components + +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.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.general.components.fingerprints.AccountListFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.AccountListParentFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.AccountMenuFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.AccountSwitcherAccessibilityLabelFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.BottomUiContainerFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.CreateSearchSuggestionsFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.FloatingMicrophoneFingerprint +import app.revanced.patches.youtube.general.components.fingerprints.TrendingSearchConfigFingerprint +import app.revanced.patches.youtube.utils.fingerprints.AccountMenuParentFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +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.AccountSwitcherAccessibility +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch +import app.revanced.patches.youtube.utils.viewgroup.ViewGroupMarginLayoutParamsHookPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getTargetIndexWithReference +import app.revanced.util.getTargetIndexWithReferenceReversed +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +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.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +@Suppress("unused") +object LayoutComponentsPatch : BaseBytecodePatch( + name = "Hide layout components", + description = "Adds options to hide general layout components.", + dependencies = setOf( + LithoFilterPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class, + ToolBarHookPatch::class, + ViewGroupMarginLayoutParamsHookPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + AccountListParentFingerprint, + AccountMenuParentFingerprint, + AccountSwitcherAccessibilityLabelFingerprint, + BottomUiContainerFingerprint, + CreateSearchSuggestionsFingerprint, + FloatingMicrophoneFingerprint, + TrendingSearchConfigFingerprint + ) +) { + private const val CUSTOM_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/CustomFilter;" + private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/LayoutComponentsFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for hide account menu + + // for you tab + AccountListParentFingerprint.resultOrThrow().let { parentResult -> + AccountListFingerprint.resolve(context, parentResult.classDef) + + AccountListFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + 3 + val targetInstruction = getInstruction(targetIndex) + + addInstruction( + targetIndex, + "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + + "$GENERAL_CLASS_DESCRIPTOR->hideAccountList(Landroid/view/View;Ljava/lang/CharSequence;)V" + ) + } + } + } + + // for tablet and old clients + AccountMenuFingerprint.resolve( + context, + AccountMenuParentFingerprint.resultOrThrow().classDef + ) + AccountMenuFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + 2 + val targetInstruction = getInstruction(targetIndex) + + addInstruction( + targetIndex, + "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + + "$GENERAL_CLASS_DESCRIPTOR->hideAccountMenu(Landroid/view/View;Ljava/lang/CharSequence;)V" + ) + } + } + + // endregion + + // region patch for 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}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I + move-result p1 + """ + ) + } ?: throw PatchException("setVisibility method not found.") + + // endregion + + // region patch for hide floating microphone + + FloatingMicrophoneFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val register = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingMicrophone(Z)Z + move-result v$register + """ + ) + } + } + + // endregion + + // region patch for hide handle + + AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility) + val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ) + val setVisibilityIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility") + val visibilityRegister = getInstruction(setVisibilityIndex).registerD + + addInstructions( + insertIndex, """ + invoke-static {v$visibilityRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHandle(I)I + move-result v$visibilityRegister + """ + ) + } + } + + // endregion + + // region patch for hide search term thumbnail + + CreateSearchSuggestionsFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + val relativeIndex = getWideLiteralInstructionIndex(40) + val replaceIndex = getTargetIndexWithReferenceReversed( + relativeIndex, + "Landroid/widget/ImageView;->setVisibility(I)V" + ) - 1 + + val jumpIndex = getTargetIndexWithReference( + relativeIndex, + "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" + ) + 4 + + val replaceIndexInstruction = getInstruction(replaceIndex) + val replaceIndexReference = + getInstruction(replaceIndex).reference + + addInstructionsWithLabels( + replaceIndex + 1, """ + invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z + move-result v${replaceIndexInstruction.registerA} + if-nez v${replaceIndexInstruction.registerA}, :hidden + iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + removeInstruction(replaceIndex) + } + } + + // endregion + + // region patch for hide snack bar + + BottomUiContainerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideSnackBar()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + } + + // endregion + + // region patch for hide toolbar button + + ToolBarHookPatch.injectCall("$GENERAL_CLASS_DESCRIPTOR->hideToolBarButton") + + // endregion + + // region patch for hide trending searches + + TrendingSearchConfigFingerprint.literalInstructionBooleanHook( + 45399984, + "$GENERAL_CLASS_DESCRIPTOR->hideTrendingSearches(Z)Z" + ) + + // endregion + + + LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR) + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: GENERAL", + "SETTINGS: HIDE_LAYOUT_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListFingerprint.kt index 84b492612..d376c358b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListParentFingerprint.kt similarity index 79% rename from src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListParentFingerprint.kt index cded93375..955ad5695 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountListParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountListParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CompactListItem import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountMenuFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountMenuFingerprint.kt index a37c9bf13..3f4c6709d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountMenuFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt index f023ffbeb..8e0672ae3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.handle.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/fingerprints/BottomUiContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/BottomUiContainerFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/general/snackbar/fingerprints/BottomUiContainerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/BottomUiContainerFingerprint.kt index 2d493600c..f8b84cea3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/fingerprints/BottomUiContainerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/BottomUiContainerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.snackbar.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/CreateSearchSuggestionsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/CreateSearchSuggestionsFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/CreateSearchSuggestionsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/CreateSearchSuggestionsFingerprint.kt index 5525720ad..5eeb747e2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/CreateSearchSuggestionsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/CreateSearchSuggestionsFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.searchterm.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/fingerprints/FloatingMicrophoneFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/FloatingMicrophoneFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/fingerprints/FloatingMicrophoneFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/FloatingMicrophoneFingerprint.kt index ca1e0ae4f..0be68d53c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/fingerprints/FloatingMicrophoneFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/FloatingMicrophoneFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.floatingmicrophone.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Fab diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/fingerprints/TrendingSearchConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/TrendingSearchConfigFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/fingerprints/TrendingSearchConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/TrendingSearchConfigFingerprint.kt index dd178b319..5c1f8f9e0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/fingerprints/TrendingSearchConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/components/fingerprints/TrendingSearchConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.trendingsearches.fingerprints +package app.revanced.patches.youtube.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/CrowdfundingBoxPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/CrowdfundingBoxPatch.kt deleted file mode 100644 index 37e36473d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/CrowdfundingBoxPatch.kt +++ /dev/null @@ -1,53 +0,0 @@ -package app.revanced.patches.youtube.general.crowdfundingbox - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.general.crowdfundingbox.fingerprints.CrowdfundingBoxFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object CrowdfundingBoxPatch : BaseBytecodePatch( - name = "Hide crowdfunding box", - description = "Adds an option to hide the crowdfunding box between the player and video description.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(CrowdfundingBoxFingerprint) -) { - override fun execute(context: BytecodeContext) { - - CrowdfundingBoxFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val register = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->hideCrowdfundingBox(Landroid/view/View;)V" - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_CROWDFUNDING_BOX" - ) - ) - - SettingsPatch.updatePatchStatus("Hide crowdfunding box") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/dialog/ViewerDiscretionDialogPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/ViewerDiscretionDialogPatch.kt index f23fc9234..08fff17c7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/dialog/ViewerDiscretionDialogPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/ViewerDiscretionDialogPatch.kt @@ -28,7 +28,6 @@ object ViewerDiscretionDialogPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Remove viewer discretion dialog") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/FloatingMicrophonePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/FloatingMicrophonePatch.kt deleted file mode 100644 index 782a524b3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/floatingmicrophone/FloatingMicrophonePatch.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.general.floatingmicrophone - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.general.floatingmicrophone.fingerprints.FloatingMicrophoneFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object FloatingMicrophonePatch : BaseBytecodePatch( - name = "Hide floating microphone", - description = "Adds an option to hide the floating microphone button when searching.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(FloatingMicrophoneFingerprint) -) { - override fun execute(context: BytecodeContext) { - - FloatingMicrophoneFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - val register = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex + 1, """ - invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingMicrophone(Z)Z - move-result v$register - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_FLOATING_MICROPHONE" - ) - ) - - SettingsPatch.updatePatchStatus("Hide floating microphone") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/handle/HandlePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/handle/HandlePatch.kt deleted file mode 100644 index 0702319b6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/handle/HandlePatch.kt +++ /dev/null @@ -1,70 +0,0 @@ -package app.revanced.patches.youtube.general.handle - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.handle.fingerprints.AccountSwitcherAccessibilityLabelFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -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.AccountSwitcherAccessibility -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object HandlePatch : BaseBytecodePatch( - name = "Hide handle", - description = "Adds options to hide the handle in the account switcher and You tab.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(AccountSwitcherAccessibilityLabelFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/HandlesFilter;" - - override fun execute(context: BytecodeContext) { - - AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility) - val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ) - val setVisibilityIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility") - val visibilityRegister = getInstruction(setVisibilityIndex).registerD - - addInstructions( - insertIndex, """ - invoke-static {v$visibilityRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHandle(I)I - move-result v$visibilityRegister - """ - ) - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_HANDLE" - ) - ) - - SettingsPatch.updatePatchStatus("Hide handle") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/LatestVideosButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/LatestVideosButtonPatch.kt deleted file mode 100644 index c1a87220a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/latestvideosbutton/LatestVideosButtonPatch.kt +++ /dev/null @@ -1,52 +0,0 @@ -package app.revanced.patches.youtube.general.latestvideosbutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.general.latestvideosbutton.fingerprints.LatestVideosButtonFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object LatestVideosButtonPatch : BaseBytecodePatch( - name = "Hide latest videos button", - description = "Adds options to hide latest videos button in home feed.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(LatestVideosButtonFingerprint) -) { - override fun execute(context: BytecodeContext) { - LatestVideosButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideLatestVideosButton(Landroid/view/View;)V" - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_LATEST_VIDEOS_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide latest videos button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt deleted file mode 100644 index 8496e2263..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt +++ /dev/null @@ -1,53 +0,0 @@ -package app.revanced.patches.youtube.general.layout - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object LayoutComponentsPatch : BaseBytecodePatch( - name = "Hide layout components", - description = "Adds options to hide general layout components.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val CHANNEL_BAR_FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ChannelBarFilter;" - private const val CUSTOM_FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/CustomFilter;" - private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/LayoutComponentsFilter;" - private const val KEYWORD_FILTER_CLASS_NAME = - "$COMPONENTS_PATH/KeywordContentFilter;" - - override fun execute(context: BytecodeContext) { - LithoFilterPatch.addFilter(CHANNEL_BAR_FILTER_CLASS_DESCRIPTOR) - LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR) - LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR) - LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: BOTTOM_PLAYER_SETTINGS", - "PREFERENCE: GENERAL_SETTINGS", - "PREFERENCE: PLAYER_SETTINGS", - - "SETTINGS: GENERAL_EXPERIMENTAL_FLAGS", - "SETTINGS: HIDE_AUDIO_TRACK_BUTTON", - "SETTINGS: HIDE_CHANNEL_BAR_BUTTON", - "SETTINGS: HIDE_LAYOUT_COMPONENTS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide layout components") - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/LayoutSwitchPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt similarity index 60% rename from src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/LayoutSwitchPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt index 8f5ab7ae3..dc8480ad5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/LayoutSwitchPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/LayoutSwitchPatch.kt @@ -1,18 +1,15 @@ -package app.revanced.patches.youtube.misc.layoutswitch +package app.revanced.patches.youtube.general.layoutswitch 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.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.misc.layoutswitch.fingerprints.GetFormFactorFingerprint -import app.revanced.patches.youtube.utils.fingerprints.LayoutSwitchFingerprint +import app.revanced.patches.youtube.general.layoutswitch.fingerprints.GetFormFactorFingerprint +import app.revanced.patches.youtube.general.layoutswitch.fingerprints.LayoutSwitchFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndexReversed import app.revanced.util.patch.BaseBytecodePatch @@ -31,18 +28,17 @@ object LayoutSwitchPatch : BaseBytecodePatch( LayoutSwitchFingerprint ) ) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/LayoutOverridePatch;" override fun execute(context: BytecodeContext) { - // tablet layout + // region patch for enable tablet layout + GetFormFactorFingerprint.resultOrThrow().let { it.mutableMethod.apply { val jumpIndex = getTargetIndexReversed(Opcode.SGET_OBJECT) addInstructionsWithLabels( 0, """ - invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->enableTabletLayout()Z + invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->enableTabletLayout()Z move-result v0 # Free register if-nez v0, :is_large_form_factor """, @@ -54,43 +50,37 @@ object LayoutSwitchPatch : BaseBytecodePatch( } } - // phone layout + // endregion + + // region patch for enable phone layout + LayoutSwitchFingerprint.resultOrThrow().let { it.mutableMethod.apply { + val insertIndex = getTargetIndex(Opcode.IF_NEZ) + val insertRegister = getInstruction(insertIndex).registerA + addInstructions( - 4, """ - invoke-static {p0}, $INTEGRATIONS_CLASS_DESCRIPTOR->getLayoutOverride(I)I - move-result p0 + insertIndex, """ + invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->enablePhoneLayout(I)I + move-result v$insertRegister """ ) } } + // endregion + /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", + "PREFERENCE_SCREEN: GENERAL", + "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS", "SETTINGS: LAYOUT_SWITCH" ) ) - SettingsPatch.updatePatchStatus("Layout switch") - - } - - private fun MutableMethod.injectEnum( - enumName: String, - fieldName: String - ) { - val stringIndex = getStringInstructionIndex(enumName) - val insertIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT) - val insertRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex + 1, - "sput-object v$insertRegister, $INTEGRATIONS_CLASS_DESCRIPTOR->$fieldName:Ljava/lang/Enum;" - ) + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/fingerprints/GetFormFactorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/GetFormFactorFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/fingerprints/GetFormFactorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/GetFormFactorFingerprint.kt index d621f9b68..c3f22c424 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/layoutswitch/fingerprints/GetFormFactorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/GetFormFactorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.layoutswitch.fingerprints +package app.revanced.patches.youtube.general.layoutswitch.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/LayoutSwitchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/LayoutSwitchFingerprint.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/LayoutSwitchFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/LayoutSwitchFingerprint.kt index 6cf923175..327df6160 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/LayoutSwitchFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/layoutswitch/fingerprints/LayoutSwitchFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.fingerprints +package app.revanced.patches.youtube.general.layoutswitch.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/loadingscreen/GradientLoadingScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/loadingscreen/GradientLoadingScreenPatch.kt index d8f7aebb0..d44432ad1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/loadingscreen/GradientLoadingScreenPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/loadingscreen/GradientLoadingScreenPatch.kt @@ -42,7 +42,6 @@ object GradientLoadingScreenPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Enable gradient loading screen") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/LoadMoreButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/LoadMoreButtonPatch.kt deleted file mode 100644 index 0e5567367..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/loadmorebutton/LoadMoreButtonPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.youtube.general.loadmorebutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patches.youtube.general.loadmorebutton.fingerprints.LoadMoreButtonFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object LoadMoreButtonPatch : BaseBytecodePatch( - name = "Hide load more button", - description = "Adds an option to hide the button under videos that loads similar videos.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(LoadMoreButtonFingerprint) -) { - override fun execute(context: BytecodeContext) { - LoadMoreButtonFingerprint.resultOrThrow().let { - val getViewMethod = - it.mutableClass.methods.find { method -> - method.parameters.isEmpty() && - method.returnType == "Landroid/view/View;" - } - - getViewMethod?.apply { - val targetIndex = implementation!!.instructions.size - 1 - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex, - "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideLoadMoreButton(Landroid/view/View;)V" - ) - } ?: throw PatchException("Failed to find getView method") - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_LOAD_MORE_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide load more button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/MixPlaylistsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/MixPlaylistsPatch.kt deleted file mode 100644 index b2afc5356..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/mixplaylists/MixPlaylistsPatch.kt +++ /dev/null @@ -1,89 +0,0 @@ -package app.revanced.patches.youtube.general.mixplaylists - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.mixplaylists.fingerprints.ElementParserFingerprint -import app.revanced.patches.youtube.general.mixplaylists.fingerprints.ElementParserParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -@Suppress("unused") -object MixPlaylistsPatch : BaseBytecodePatch( - name = "Hide mix playlists", - description = "Adds an option to hide mix playlists in feed.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(ElementParserParentFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/MixPlaylistsFilter;" - - override fun execute(context: BytecodeContext) { - - ElementParserParentFingerprint.resultOrThrow().let { parentResult -> - ElementParserFingerprint.resolve(context, parentResult.classDef) - - ElementParserFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val freeRegister = implementation!!.registerCount - parameters.size - 2 - val insertIndex = indexOfFirstInstruction { - val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference) - - reference?.parameterTypes?.size == 1 - && reference.parameterTypes.first() == "[B" - && reference.returnType.startsWith("L") - } - - val objectIndex = getTargetIndex(Opcode.MOVE_OBJECT) - val objectRegister = getInstruction(objectIndex).registerA - - val jumpIndex = it.scanResult.patternScanResult!!.startIndex - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {v$objectRegister, v$freeRegister}, $FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z - move-result v$freeRegister - if-nez v$freeRegister, :filter - """, ExternalLabel("filter", getInstruction(jumpIndex)) - ) - - addInstruction( - 0, - "move-object/from16 v$freeRegister, p3" - ) - } - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_MIX_PLAYLISTS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide mix playlists") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt new file mode 100644 index 000000000..ebeb9729f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt @@ -0,0 +1,113 @@ +package app.revanced.patches.youtube.general.navigation + +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.patches.youtube.general.navigation.fingerprints.AutoMotiveFingerprint +import app.revanced.patches.youtube.general.navigation.fingerprints.PivotBarChangedFingerprint +import app.revanced.patches.youtube.general.navigation.fingerprints.PivotBarSetTextFingerprint +import app.revanced.patches.youtube.general.navigation.fingerprints.PivotBarStyleFingerprint +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.navigation.NavigationBarHookPatch +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getStringInstructionIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Suppress("unused") +object NavigationBarComponentsPatch : BaseBytecodePatch( + name = "Hide navigation bar components", + description = "Adds options to hide components related to navigation bar.", + dependencies = setOf( + SettingsPatch::class, + NavigationBarHookPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + AutoMotiveFingerprint, + PivotBarChangedFingerprint, + PivotBarSetTextFingerprint, + PivotBarStyleFingerprint + ) +) { + override fun execute(context: BytecodeContext) { + + // region patch for enable narrow navigation buttons + + arrayOf( + PivotBarChangedFingerprint, + PivotBarStyleFingerprint + ).forEach { fingerprint -> + fingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + 1 + val register = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->enableNarrowNavigationButton(Z)Z + move-result v$register + """ + ) + } + } + } + + // endregion + + // region patch for hide navigation buttons + + AutoMotiveFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getStringInstructionIndex("Android Automotive") - 1 + val register = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z + move-result v$register + """ + ) + } + } + + // endregion + + // region patch for hide navigation label + + PivotBarSetTextFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getTargetIndexWithMethodReferenceName("setText") + val targetRegister = getInstruction(targetIndex).registerC + + addInstruction( + targetIndex, + "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V" + ) + } + } + + // endregion + + + // Hook navigation button created, in order to hide them. + NavigationBarHookPatch.hookNavigationButtonCreated(GENERAL_CLASS_DESCRIPTOR) + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: GENERAL", + "SETTINGS: HIDE_NAVIGATION_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/AutoMotiveFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/AutoMotiveFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/AutoMotiveFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/AutoMotiveFingerprint.kt index 495cd81f1..e93799c2e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/AutoMotiveFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/AutoMotiveFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints +package app.revanced.patches.youtube.general.navigation.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarChangedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarChangedFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarChangedFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarChangedFingerprint.kt index 726bb3d13..a6e5a3720 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarChangedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarChangedFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.navigation.tabletnavbar.fingerprints +package app.revanced.patches.youtube.general.navigation.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/label/fingerprints/PivotBarSetTextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarSetTextFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/youtube/navigation/label/fingerprints/PivotBarSetTextFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarSetTextFingerprint.kt index ebda48a82..5c0dd386b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/label/fingerprints/PivotBarSetTextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarSetTextFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.navigation.label.fingerprints +package app.revanced.patches.youtube.general.navigation.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarStyleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarStyleFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarStyleFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarStyleFingerprint.kt index d58faf9c9..6f89aff7a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/fingerprints/PivotBarStyleFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/fingerprints/PivotBarStyleFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.navigation.tabletnavbar.fingerprints +package app.revanced.patches.youtube.general.navigation.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt deleted file mode 100644 index 3333be9ac..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt +++ /dev/null @@ -1,71 +0,0 @@ -package app.revanced.patches.youtube.general.searchterm - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.general.searchterm.fingerprints.CreateSearchSuggestionsFingerprint -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.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithReference -import app.revanced.util.getTargetIndexWithReferenceReversed -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object SearchTermThumbnailPatch : BaseBytecodePatch( - name = "Hide search term thumbnail", - description = "Adds an option to hide thumbnails in the search term history.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(CreateSearchSuggestionsFingerprint) -) { - override fun execute(context: BytecodeContext) { - CreateSearchSuggestionsFingerprint.resultOrThrow().let { result -> - result.mutableMethod.apply { - val relativeIndex = getWideLiteralInstructionIndex(40) - val replaceIndex = getTargetIndexWithReferenceReversed( - relativeIndex, - "Landroid/widget/ImageView;->setVisibility(I)V" - ) - 1 - - val jumpIndex = getTargetIndexWithReference( - relativeIndex, - "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" - ) + 4 - - val replaceIndexInstruction = getInstruction(replaceIndex) - val replaceIndexReference = - getInstruction(replaceIndex).reference - - addInstructionsWithLabels( - replaceIndex + 1, """ - invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z - move-result v${replaceIndexInstruction.registerA} - if-nez v${replaceIndexInstruction.registerA}, :hidden - iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) - removeInstruction(replaceIndex) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_SEARCH_TERM_THUMBNAIL" - ) - ) - - SettingsPatch.updatePatchStatus("Hide search term thumbnail") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarPatch.kt deleted file mode 100644 index ae9d8bd26..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarPatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.youtube.general.snackbar - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.general.snackbar.fingerprints.BottomUiContainerFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object SnackBarPatch : BaseBytecodePatch( - name = "Hide snack bar", - description = "Adds an option to hide the snack bar action popup.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(BottomUiContainerFingerprint) -) { - override fun execute(context: BytecodeContext) { - - BottomUiContainerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideSnackBar()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_SNACK_BAR" - ) - ) - - SettingsPatch.updatePatchStatus("Hide snack bar") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/SongSearchPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/SongSearchPatch.kt deleted file mode 100644 index ff65d34aa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/SongSearchPatch.kt +++ /dev/null @@ -1,47 +0,0 @@ -package app.revanced.patches.youtube.general.songsearch - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.PatchException -import app.revanced.patches.youtube.general.songsearch.fingerprints.VoiceSearchConfigFingerprint -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.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object SongSearchPatch : BaseBytecodePatch( - name = "Enable song search", - description = "Adds an option to enable song search in the voice search screen.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(VoiceSearchConfigFingerprint), - use = false -) { - override fun execute(context: BytecodeContext) { - - VoiceSearchConfigFingerprint.result?.let { - it.mutableMethod.apply { - addInstructions( - 0, """ - invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->enableSongSearch()Z - move-result v0 - return v0 - """ - ) - } - } ?: throw PatchException("This version is not supported. Please use YouTube 18.30.37 or later.") - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: ENABLE_SONG_SEARCH" - ) - ) - - SettingsPatch.updatePatchStatus("Enable song search") - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/fingerprints/VoiceSearchConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/fingerprints/VoiceSearchConfigFingerprint.kt deleted file mode 100644 index 714eae68a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/songsearch/fingerprints/VoiceSearchConfigFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.general.songsearch.fingerprints - -import app.revanced.util.fingerprint.LiteralValueFingerprint - -/** - * This fingerprint is compatible with YouTube v18.30.37+ - */ -internal object VoiceSearchConfigFingerprint : LiteralValueFingerprint( - returnType = "Z", - literalSupplier = { 45417109 } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/ChannelProfileComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt similarity index 50% rename from src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/ChannelProfileComponentsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt index bac4baffa..1db89e094 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/channelprofile/ChannelProfileComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt @@ -1,62 +1,59 @@ -package app.revanced.patches.youtube.general.channelprofile +package app.revanced.patches.youtube.general.splashanimation 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.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.channelprofile.fingerprints.DefaultsTabsBarFingerprint +import app.revanced.patches.youtube.general.splashanimation.fingerprints.SplashAnimationFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +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.TabsBarTextTabView +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getTargetIndexReversed import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") -object ChannelProfileComponentsPatch : BaseBytecodePatch( - name = "Hide channel profile components", - description = "Adds an option to hide channel profile components.", +object SplashAnimationPatch : BaseBytecodePatch( + name = "Disable splash animation", + description = "Adds an option to disable splash animation.", dependencies = setOf( - LithoFilterPatch::class, SettingsPatch::class, SharedResourceIdPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(DefaultsTabsBarFingerprint) + fingerprints = setOf(SplashAnimationFingerprint) ) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ChannelProfileFilter;" - override fun execute(context: BytecodeContext) { - DefaultsTabsBarFingerprint.resultOrThrow().let { + SplashAnimationFingerprint.resultOrThrow().let { it.mutableMethod.apply { - val viewIndex = getWideLiteralInstructionIndex(TabsBarTextTabView) + 2 - val viewRegister = getInstruction(viewIndex).registerA + val constIndex = getWideLiteralInstructionIndex(DarkSplashAnimation) + val targetIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_STATIC) + 2 + val targetRegister = getInstruction(targetIndex - 1).registerA - addInstruction( - viewIndex + 1, - "sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->channelTabView:Landroid/view/View;" + addInstructions( + targetIndex, """ + invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->disableSplashAnimation(Z)Z + move-result v$targetRegister + """ ) } } - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - /** * Add settings */ SettingsPatch.addPreference( arrayOf( "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_CHANNEL_PROFILE_COMPONENTS" + "SETTINGS: DISABLE_SPLASH_ANIMATION" ) ) - SettingsPatch.updatePatchStatus("Hide channel profile components") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/fingerprints/SplashAnimationFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/fingerprints/SplashAnimationFingerprint.kt new file mode 100644 index 000000000..59d0ec246 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/fingerprints/SplashAnimationFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.general.splashanimation.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation +import app.revanced.util.containsWideLiteralInstructionIndex + +internal object SplashAnimationFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("Landroid/os/Bundle;"), + customFingerprint = { methodDef, _ -> + methodDef.name == "onCreate" + && methodDef.containsWideLiteralInstructionIndex(DarkSplashAnimation) + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionBytecodePatch.kt similarity index 53% rename from src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionBytecodePatch.kt index 6ba283525..b5f278efb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionBytecodePatch.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.misc.spoofappversion +package app.revanced.patches.youtube.general.spoofappversion import app.revanced.patches.shared.spoofappversion.BaseSpoofAppVersionPatch -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR object SpoofAppVersionBytecodePatch : BaseSpoofAppVersionPatch( - "$MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" + "$GENERAL_CLASS_DESCRIPTOR->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt similarity index 78% rename from src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt index 1968a0be1..acb275f53 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt @@ -1,9 +1,8 @@ -package app.revanced.patches.youtube.misc.spoofappversion +package app.revanced.patches.youtube.general.spoofappversion import app.revanced.patcher.data.ResourceContext import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseResourcePatch import org.w3c.dom.Element @@ -20,32 +19,27 @@ object SpoofAppVersionPatch : BaseResourcePatch( ) { override fun execute(context: ResourceContext) { - /** - * Copy arrays - */ - context.copyXmlNode("youtube/spoofappversion/host", "values/arrays.xml", "resources") - if (SettingsPatch.upward1834) { context.appendChild( arrayOf( - "revanced_spoof_app_version_target_entry" to "@string/revanced_spoof_app_version_target_entry_18_33_40", - "revanced_spoof_app_version_target_entry_value" to "18.33.40", + "revanced_spoof_app_version_target_entries" to "@string/revanced_spoof_app_version_target_entry_18_33_40", + "revanced_spoof_app_version_target_entry_values" to "18.33.40", ) ) if (SettingsPatch.upward1839) { context.appendChild( arrayOf( - "revanced_spoof_app_version_target_entry" to "@string/revanced_spoof_app_version_target_entry_18_38_45", - "revanced_spoof_app_version_target_entry_value" to "18.38.45" + "revanced_spoof_app_version_target_entries" to "@string/revanced_spoof_app_version_target_entry_18_38_45", + "revanced_spoof_app_version_target_entry_values" to "18.38.45" ) ) if (SettingsPatch.upward1849) { context.appendChild( arrayOf( - "revanced_spoof_app_version_target_entry" to "@string/revanced_spoof_app_version_target_entry_18_48_39", - "revanced_spoof_app_version_target_entry_value" to "18.48.39" + "revanced_spoof_app_version_target_entries" to "@string/revanced_spoof_app_version_target_entry_18_48_39", + "revanced_spoof_app_version_target_entry_values" to "18.48.39" ) ) } @@ -57,13 +51,13 @@ object SpoofAppVersionPatch : BaseResourcePatch( */ SettingsPatch.addPreference( arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", + "PREFERENCE_SCREEN: GENERAL", + "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS", "SETTINGS: SPOOF_APP_VERSION" ) ) - SettingsPatch.updatePatchStatus("Spoof app version") - + SettingsPatch.updatePatchStatus(this) } private fun ResourceContext.appendChild(entryArray: Array>) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt index 287e24425..0044542b2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt @@ -6,8 +6,6 @@ import app.revanced.patches.youtube.general.startpage.fingerprints.StartActivity 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.settings.SettingsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts -import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow @@ -29,22 +27,16 @@ object ChangeStartPagePatch : BaseBytecodePatch( } } - /** - * Copy arrays - */ - contexts.copyXmlNode("youtube/startpage/host", "values/arrays.xml", "resources") - /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: GENERAL_SETTINGS", + "PREFERENCE_SCREEN: GENERAL", "SETTINGS: CHANGE_START_PAGE" ) ) - SettingsPatch.updatePatchStatus("Change start page") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/SuggestionsShelfPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/SuggestionsShelfPatch.kt deleted file mode 100644 index 2f5bcd2f6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/suggestionshelf/SuggestionsShelfPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtube.general.suggestionshelf - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.suggestionshelf.fingerprints.BreakingNewsFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.navbarindex.NavBarIndexHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object SuggestionsShelfPatch : BaseBytecodePatch( - name = "Hide suggestions shelf", - description = "Adds an option to hide the suggestions shelf in feed.", - dependencies = setOf( - LithoFilterPatch::class, - NavBarIndexHookPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(BreakingNewsFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/SuggestionsShelfFilter;" - - override fun execute(context: BytecodeContext) { - - /** - * Only used to tablet layout. - */ - BreakingNewsFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $FILTER_CLASS_DESCRIPTOR->hideBreakingNewsShelf(Landroid/view/View;)V" - ) - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_SUGGESTIONS_SHELF" - ) - ) - - SettingsPatch.updatePatchStatus("Hide suggestions shelf") - - } -} 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 16cf7ef39..e810208be 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 @@ -75,8 +75,7 @@ object TabletMiniPlayerPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Enable tablet mini player") - + SettingsPatch.updatePatchStatus(this) } private fun MutableMethod.hook(index: Int) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarButtonPatch.kt deleted file mode 100644 index f1f097d42..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarButtonPatch.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.youtube.general.toolbar - -import app.revanced.patcher.data.BytecodeContext -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.settings.SettingsPatch -import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object ToolBarButtonPatch : BaseBytecodePatch( - name = "Hide toolbar button", - description = "Adds an option to hide the button in the toolbar.", - dependencies = setOf( - SettingsPatch::class, - ToolBarHookPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - override fun execute(context: BytecodeContext) { - - ToolBarHookPatch.injectCall("$GENERAL_CLASS_DESCRIPTOR->hideToolBarButton") - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_TOOLBAR_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide toolbar button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/TrendingSearchesPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/TrendingSearchesPatch.kt deleted file mode 100644 index 6a216487b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/general/trendingsearches/TrendingSearchesPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.youtube.general.trendingsearches - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.youtube.general.trendingsearches.fingerprints.TrendingSearchConfigFingerprint -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.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object TrendingSearchesPatch : BaseBytecodePatch( - name = "Hide trending searches", - description = "Adds an option to hide trending searches in the search bar.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TrendingSearchConfigFingerprint) -) { - override fun execute(context: BytecodeContext) { - - TrendingSearchConfigFingerprint.literalInstructionBooleanHook( - 45399984, - "$GENERAL_CLASS_DESCRIPTOR->hideTrendingSearches(Z)Z" - ) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: GENERAL_SETTINGS", - "SETTINGS: HIDE_TRENDING_SEARCHES" - ) - ) - - SettingsPatch.updatePatchStatus("Hide trending searches") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/widesearchbar/WideSearchBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/widesearchbar/WideSearchBarPatch.kt index 7128ebf82..ea969d83d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/widesearchbar/WideSearchBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/widesearchbar/WideSearchBarPatch.kt @@ -86,8 +86,7 @@ object WideSearchBarPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Enable wide search bar") - + SettingsPatch.updatePatchStatus(this) } /** diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/animated/AnimatedButtonBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/animated/AnimatedButtonBackgroundPatch.kt index 51022e21f..af407eead 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/animated/AnimatedButtonBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/animated/AnimatedButtonBackgroundPatch.kt @@ -28,6 +28,6 @@ object AnimatedButtonBackgroundPatch : BaseResourcePatch( ) ) - SettingsPatch.updatePatchStatus("Hide animated button background") + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt index 712355543..6d9bde30e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt @@ -9,7 +9,6 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.ResourceGroup import app.revanced.util.copyResources import app.revanced.util.patch.BaseResourcePatch -import org.w3c.dom.Element import java.io.File import java.nio.file.Files @@ -141,14 +140,6 @@ object CustomBrandingIconPatch : BaseResourcePatch( context.copyResources("$resourcePath/monochrome", resourceGroup) } - // disable splash animation. - context.xmlEditor["res/values-v31/styles.xml"].use { editor -> - val tags = editor.file.getElementsByTagName("item") - List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("name").contains("android:windowSplashScreenAnimatedIcon") } - .forEach { it.parentNode.removeChild(it) } - } - context.updatePatchStatusIcon(appIconValue) } } ?: throw PatchException("Invalid app icon path.") diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt index 3df728f87..82edae4a4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt @@ -5,7 +5,6 @@ import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.LANGUAGE_LIST import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusLabel import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.patch.BaseResourcePatch @@ -32,9 +31,7 @@ object CustomBrandingNamePatch : BaseResourcePatch( ) override fun execute(context: ResourceContext) { - context.removeStringsElements( - LANGUAGE_LIST, arrayOf("application_name") ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/doubletapbackground/DoubleTapOverlayBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/doubletapbackground/DoubleTapOverlayBackgroundPatch.kt index 5cbc3b0c9..45eb6a32f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/doubletapbackground/DoubleTapOverlayBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/doubletapbackground/DoubleTapOverlayBackgroundPatch.kt @@ -21,7 +21,6 @@ object DoubleTapOverlayBackgroundPatch : BaseResourcePatch( arrayOf("tap_bloom_view", "dark_background") ) - SettingsPatch.updatePatchStatus("Hide double tap overlay filter") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/doubletaplength/DoubleTapLengthPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/doubletaplength/DoubleTapLengthPatch.kt index d7a689860..b8999573f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/doubletaplength/DoubleTapLengthPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/doubletaplength/DoubleTapLengthPatch.kt @@ -9,8 +9,9 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.ResourceGroup import app.revanced.util.copyResources import app.revanced.util.patch.BaseResourcePatch +import java.nio.file.Files -@Suppress("unused") +@Suppress("DEPRECATION", "unused") object DoubleTapLengthPatch : BaseResourcePatch( name = "Custom double tap length", description = "Add 'double-tap to seek' value.", @@ -30,6 +31,10 @@ object DoubleTapLengthPatch : BaseResourcePatch( val entriesName = "double_tap_length_entries" val entryValueName = "double_tap_length_values" + val valuesV21Directory = context["res"].resolve("values-v21") + if (!valuesV21Directory.isDirectory) + Files.createDirectories(valuesV21Directory.toPath()) + /** * Copy arrays */ @@ -52,7 +57,6 @@ object DoubleTapLengthPatch : BaseResourcePatch( context.addEntryValues(arrayPath, lengthElements[index], entriesName) } - SettingsPatch.updatePatchStatus("Custom double tap length") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/pipnotification/PiPNotificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/pipnotification/PiPNotificationPatch.kt index a9fff35f6..4776e45a6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/pipnotification/PiPNotificationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/pipnotification/PiPNotificationPatch.kt @@ -46,10 +46,6 @@ object PiPNotificationPatch : BaseBytecodePatch( } } - /** - * Add settings - */ - SettingsPatch.updatePatchStatus("Disable pip notification") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbg/PlayerButtonBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbg/PlayerButtonBackgroundPatch.kt index c86a7becd..6ab351d25 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbg/PlayerButtonBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbg/PlayerButtonBackgroundPatch.kt @@ -29,7 +29,6 @@ object PlayerButtonBackgroundPatch : BaseResourcePatch( } } - SettingsPatch.updatePatchStatus("Hide player button background") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/splashanimation/AddSplashAnimationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/splashanimation/AddSplashAnimationPatch.kt deleted file mode 100644 index c3eaa6ba6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/splashanimation/AddSplashAnimationPatch.kt +++ /dev/null @@ -1,60 +0,0 @@ -package app.revanced.patches.youtube.layout.splashanimation - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.ResourceGroup -import app.revanced.util.copyResources -import app.revanced.util.copyXmlNode -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("DEPRECATION", "unused") -object AddSplashAnimationPatch : BaseResourcePatch( - name = "Add splash animation", - description = "Adds old style splash animation.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - use = false -) { - override fun execute(context: ResourceContext) { - - /** - * avd_anim.xml removed from YouTube v18.19.36+ - */ - val targetXml = context["res"].resolve("drawable").resolve("avd_anim.xml") - - if (!targetXml.exists()) { - - /** - * merge Splash animation drawables to main drawables - * extract from YouTube v18.18.39 - */ - arrayOf( - ResourceGroup( - "drawable", - "\$\$avd_anim__1__0.xml", - "\$\$avd_anim__1__1.xml", - "\$\$avd_anim__2__0.xml", - "\$\$avd_anim__2__1.xml", - "\$\$avd_anim__3__0.xml", - "\$\$avd_anim__3__1.xml", - "\$avd_anim__0.xml", - "\$avd_anim__1.xml", - "\$avd_anim__2.xml", - "\$avd_anim__3.xml", - "\$avd_anim__4.xml", - "avd_anim.xml" - ) - ).forEach { resourceGroup -> - context.copyResources("youtube/splashscreen", resourceGroup) - } - - /** - * merge Splash animation styles to main styles - * extract from YouTube v18.18.39 - */ - context.copyXmlNode("youtube/splashscreen", "values-v31/styles.xml", "resources") - } - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/TooltipContentViewPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/TooltipContentViewPatch.kt index 39a891e6c..75b6a62e3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/TooltipContentViewPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/TooltipContentViewPatch.kt @@ -2,6 +2,7 @@ package app.revanced.patches.youtube.layout.tooltip import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patches.youtube.layout.tooltip.fingerprints.TooltipContentFullscreenFingerprint import app.revanced.patches.youtube.layout.tooltip.fingerprints.TooltipContentViewFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch @@ -18,19 +19,23 @@ object TooltipContentViewPatch : BaseBytecodePatch( SharedResourceIdPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TooltipContentViewFingerprint) + fingerprints = setOf( + TooltipContentFullscreenFingerprint, + TooltipContentViewFingerprint + ) ) { override fun execute(context: BytecodeContext) { - TooltipContentViewFingerprint.resultOrThrow().mutableMethod.addInstruction( - 0, - "return-void" - ) - - /** - * Add settings - */ - SettingsPatch.updatePatchStatus("Hide tooltip content") + arrayOf( + TooltipContentFullscreenFingerprint, + TooltipContentViewFingerprint + ).forEach { fingerprint -> + fingerprint.resultOrThrow().mutableMethod.addInstruction( + 0, + "return-void" + ) + } + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/fingerprints/TooltipContentFullscreenFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/fingerprints/TooltipContentFullscreenFingerprint.kt new file mode 100644 index 000000000..488c39acd --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tooltip/fingerprints/TooltipContentFullscreenFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.layout.tooltip.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +internal object TooltipContentFullscreenFingerprint : LiteralValueFingerprint( + returnType = "V", + literalSupplier = { 45384061 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/translations/TranslationsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/youtube/misc/translations/TranslationsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt index f7e25dacb..96592e12e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/translations/TranslationsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.translations +package app.revanced.patches.youtube.layout.translations import app.revanced.patcher.data.ResourceContext import app.revanced.patches.shared.translations.TranslationsUtils.copyXml @@ -43,6 +43,6 @@ object TranslationsPatch : BaseResourcePatch( ) ) - SettingsPatch.updatePatchStatus("Translations") + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/voicesearch/VoiceSearchButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/voicesearch/VoiceSearchButtonPatch.kt index a9dc29374..b57732ed7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/voicesearch/VoiceSearchButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/voicesearch/VoiceSearchButtonPatch.kt @@ -31,6 +31,6 @@ object VoiceSearchButtonPatch : BaseResourcePatch( ) ) - SettingsPatch.updatePatchStatus("Hide voice search button") + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecBytecodePatch.kt deleted file mode 100644 index 333f30c70..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecBytecodePatch.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.audio - -import app.revanced.patches.shared.opus.BaseOpusCodecsPatch -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH - -object ForceOpusCodecBytecodePatch : BaseOpusCodecsPatch( - "$MISC_PATH/CodecOverridePatch;->shouldForceOpus()Z" -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecPatch.kt deleted file mode 100644 index 9550e678b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/audio/ForceOpusCodecPatch.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.audio - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object ForceOpusCodecPatch : BaseResourcePatch( - name = "Force opus codec", - description = "Adds an option to force the opus audio codec instead of the mp4a audio codec.", - dependencies = setOf( - ForceOpusCodecBytecodePatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - override fun execute(context: ResourceContext) { - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", - "SETTINGS: ENABLE_OPUS_CODEC" - ) - ) - - SettingsPatch.updatePatchStatus("Force opus codec") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/ForceVideoCodecPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/ForceVideoCodecPatch.kt deleted file mode 100644 index a3d908c9b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/ForceVideoCodecPatch.kt +++ /dev/null @@ -1,124 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.video - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.fingerprint.MethodFingerprintResult -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.misc.codec.video.fingerprints.VideoPrimaryFingerprint -import app.revanced.patches.youtube.misc.codec.video.fingerprints.VideoPropsFingerprint -import app.revanced.patches.youtube.misc.codec.video.fingerprints.VideoPropsParentFingerprint -import app.revanced.patches.youtube.misc.codec.video.fingerprints.VideoSecondaryFingerprint -import app.revanced.patches.youtube.utils.fingerprints.LayoutSwitchFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithFieldReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object ForceVideoCodecPatch : BaseBytecodePatch( - name = "Force video codec", - description = "Adds an option to force the video codec.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - LayoutSwitchFingerprint, - VideoPropsParentFingerprint - ) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/CodecOverridePatch;" - - private const val INTEGRATIONS_CLASS_METHOD_REFERENCE = - "$INTEGRATIONS_CLASS_DESCRIPTOR->shouldForceCodec(Z)Z" - - override fun execute(context: BytecodeContext) { - - LayoutSwitchFingerprint.resultOrThrow().classDef.let { classDef -> - arrayOf( - VideoPrimaryFingerprint, - VideoSecondaryFingerprint - ).forEach { fingerprint -> - fingerprint.also { it.resolve(context, classDef) }.resultOrThrow().injectOverride() - } - } - - VideoPropsParentFingerprint.resultOrThrow().let { parentResult -> - VideoPropsFingerprint.also { - it.resolve( - context, - parentResult.classDef - ) - }.resultOrThrow().mutableMethod.let { - mapOf( - "MANUFACTURER" to "getManufacturer", - "BRAND" to "getBrand", - "MODEL" to "getModel" - ).forEach { (fieldName, descriptor) -> - it.hookProps(fieldName, descriptor) - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", - "SETTINGS: ENABLE_VIDEO_CODEC" - ) - ) - - SettingsPatch.updatePatchStatus("Force video codec") - - } - - private fun MethodFingerprintResult.injectOverride() { - mutableMethod.apply { - val startIndex = scanResult.patternScanResult!!.startIndex - val endIndex = scanResult.patternScanResult!!.endIndex - - val startRegister = getInstruction(startIndex).registerA - val endRegister = getInstruction(endIndex).registerA - - hookOverride(endIndex + 1, endRegister) - removeInstruction(endIndex) - hookOverride(startIndex + 1, startRegister) - removeInstruction(startIndex) - } - } - - private fun MutableMethod.hookOverride( - index: Int, - register: Int - ) { - addInstructions( - index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_METHOD_REFERENCE - move-result v$register - return v$register - """ - ) - } - - private fun MutableMethod.hookProps( - fieldName: String, - descriptor: String - ) { - val index = getTargetIndexWithFieldReferenceName(fieldName) - val register = getInstruction(index).registerA - - addInstructions( - index + 1, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->$descriptor(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) - } - -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPrimaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPrimaryFingerprint.kt deleted file mode 100644 index c4342122a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPrimaryFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.video.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 VideoPrimaryFingerprint : MethodFingerprint( - returnType = "Z", - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("I"), - opcodes = listOf( - Opcode.RETURN, - Opcode.RETURN - ) -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsFingerprint.kt deleted file mode 100644 index 96c7e9c88..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.video.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 VideoPropsFingerprint : MethodFingerprint( - returnType = "L", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf(Opcode.OR_INT_LIT16) -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsParentFingerprint.kt deleted file mode 100644 index 64afb8428..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoPropsParentFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.video.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -internal object VideoPropsParentFingerprint : MethodFingerprint( - returnType = "V", - strings = listOf("Android Wear") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoSecondaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoSecondaryFingerprint.kt deleted file mode 100644 index e4e9b63bc..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/codec/video/fingerprints/VideoSecondaryFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.misc.codec.video.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 VideoSecondaryFingerprint : MethodFingerprint( - returnType = "Z", - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("L", "I"), - opcodes = listOf( - Opcode.RETURN, - Opcode.CONST_4, - Opcode.RETURN - ) -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt index cc3e0efee..0ae0b3d0a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt @@ -10,8 +10,7 @@ object DebuggingPatch : BaseResourcePatch( name = "Enable debug logging", description = "Adds an option to enable debug logging.", dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - use = false + compatiblePackages = COMPATIBLE_PACKAGE ) { override fun execute(context: ResourceContext) { @@ -24,8 +23,6 @@ object DebuggingPatch : BaseResourcePatch( ) ) - SettingsPatch.updatePatchStatus("Enable debug logging") - - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt index bb59768cf..57d18ddb5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/OpenLinksExternallyPatch.kt @@ -26,6 +26,6 @@ object OpenLinksExternallyPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Enable external browser") + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/language/LanguageSelectorPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/language/LanguageSelectorPatch.kt deleted file mode 100644 index 2a6c24d5a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/language/LanguageSelectorPatch.kt +++ /dev/null @@ -1,58 +0,0 @@ -package app.revanced.patches.youtube.misc.language - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.misc.language.fingerprints.GeneralPrefsFingerprint -import app.revanced.patches.youtube.misc.language.fingerprints.GeneralPrefsLegacyFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.exception -import app.revanced.util.patch.BaseBytecodePatch -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object LanguageSelectorPatch : BaseBytecodePatch( - name = "Enable language switch", - description = "Adds an option to enable or disable language switching toggle.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - GeneralPrefsFingerprint, - GeneralPrefsLegacyFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - val result = GeneralPrefsFingerprint.result // YouTube v18.33.xx ~ - ?: GeneralPrefsLegacyFingerprint.result // ~ YouTube v18.32.xx - ?: throw GeneralPrefsFingerprint.exception - - result.let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - 2 - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {}, $MISC_PATH/LanguageSelectorPatch;->enableLanguageSwitch()Z - move-result v$insertRegister - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: ENABLE_LANGUAGE_SWITCH" - ) - ) - - SettingsPatch.updatePatchStatus("Enable language switch") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsFingerprint.kt deleted file mode 100644 index 2b06a07e6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.youtube.misc.language.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -/** - * Compatible with YouTube v18.33.40~ - */ -internal object GeneralPrefsFingerprint : MethodFingerprint( - returnType = "V", - parameters = emptyList(), - opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT - ), - strings = listOf("bedtime_reminder_toggle"), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/GeneralPrefsFragment;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsLegacyFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsLegacyFingerprint.kt deleted file mode 100644 index 8c9c944fa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/language/fingerprints/GeneralPrefsLegacyFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.misc.language.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -/** - * Compatible with ~YouTube v18.32.39 - */ -internal object GeneralPrefsLegacyFingerprint : MethodFingerprint( - returnType = "V", - parameters = emptyList(), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.CONST_WIDE_32, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT - ), - strings = listOf("bedtime_reminder_toggle"), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/GeneralPrefsFragment;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt index db4753fb2..853f6b07d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt @@ -10,8 +10,8 @@ import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.Minimize import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.PiPControllerFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.integrations.IntegrationsPatch import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getWalkerMethod import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow @@ -24,8 +24,8 @@ object MinimizedPlaybackPatch : BaseBytecodePatch( name = "Enable minimized playback", description = "Enables minimized and background playback.", dependencies = setOf( - IntegrationsPatch::class, - PlayerTypeHookPatch::class + PlayerTypeHookPatch::class, + SettingsPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( @@ -91,5 +91,7 @@ object MinimizedPlaybackPatch : BaseBytecodePatch( ) } } + + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt index 0221e22b2..47080ff71 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/OpenLinksDirectlyPatch.kt @@ -56,7 +56,6 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch( ) ) - SettingsPatch.updatePatchStatus("Enable open links directly") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/quic/QUICProtocolPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/quic/QUICProtocolPatch.kt index d82f90e27..49f219f79 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/quic/QUICProtocolPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/quic/QUICProtocolPatch.kt @@ -40,12 +40,10 @@ object QUICProtocolPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", "SETTINGS: DISABLE_QUIC_PROTOCOL" ) ) - SettingsPatch.updatePatchStatus("Disable QUIC protocol") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/NewSplashAnimationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/NewSplashAnimationPatch.kt deleted file mode 100644 index ebab9ec19..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/NewSplashAnimationPatch.kt +++ /dev/null @@ -1,115 +0,0 @@ -package app.revanced.patches.youtube.misc.splashanimation - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.misc.splashanimation.fingerprints.WatchWhileActivityWithOutFlagsFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch -import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch.mainActivityMutableClass -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -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.TwoRegisterInstruction - -@Suppress("unused") -object NewSplashAnimationPatch : BaseBytecodePatch( - name = "Enable new splash animation", - description = "Adds an option to enable a new type of splash animation.", - dependencies = setOf( - MainActivityResolvePatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/SplashAnimationPatch;" - - override fun execute(context: BytecodeContext) { - WatchWhileActivityWithOutFlagsFingerprint.resolve(context, mainActivityMutableClass) - - /** - * YouTube v18.28.xx~ - */ - WatchWhileActivityWithOutFlagsFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - var startIndex = getWideLiteralInstructionIndex(DarkSplashAnimation) - 1 - val endIndex = startIndex - 30 - - for (index in startIndex downTo endIndex) { - if (getInstruction(index).opcode != Opcode.IF_EQZ) - continue - - startIndex = index - 8 - - arrayOf( - index, - index - 8 - ).forEach { insertIndex -> injectCall(insertIndex) } - - break - } - - for (index in startIndex downTo endIndex) { - if (getInstruction(index).opcode != Opcode.IF_NE) - continue - - injectCall(index) - - break - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: ENABLE_NEW_SPLASH_ANIMATION" - ) - ) - - SettingsPatch.updatePatchStatus("Enable new splash animation") - - } - - private fun MutableMethod.injectCall( - index: Int - ) { - if (getInstruction(index).opcode == Opcode.IF_NE) - injectInt(index) - else - injectBoolean(index) - } - - private fun MutableMethod.injectBoolean(index: Int) { - val register = getInstruction(index).registerA - - addInstructions( - index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enableNewSplashAnimationBoolean(Z)Z - move-result v$register - """ - ) - } - - private fun MutableMethod.injectInt(index: Int) { - val register = getInstruction(index).registerA - - addInstructions( - index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enableNewSplashAnimationInt(I)I - move-result v$register - """ - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/fingerprints/WatchWhileActivityWithOutFlagsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/fingerprints/WatchWhileActivityWithOutFlagsFingerprint.kt deleted file mode 100644 index c623e38d5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/splashanimation/fingerprints/WatchWhileActivityWithOutFlagsFingerprint.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.youtube.misc.splashanimation.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.Opcode - -internal object WatchWhileActivityWithOutFlagsFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("Landroid/os/Bundle;"), - opcodes = listOf( - Opcode.IF_EQZ, // target - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ // target - ), - customFingerprint = { methodDef, _ -> - methodDef.name == "onCreate" - && methodDef.containsWideLiteralInstructionIndex(DarkSplashAnimation) - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/SpoofDeviceDimensionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/SpoofDeviceDimensionsPatch.kt deleted file mode 100644 index dcefeebb0..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/SpoofDeviceDimensionsPatch.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.misc.spoofdimensions - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patches.youtube.misc.spoofdimensions.fingerprints.DeviceDimensionsModelToStringFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.util.MethodUtil - -@Suppress("unused") -object SpoofDeviceDimensionsPatch : BaseBytecodePatch( - 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.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(DeviceDimensionsModelToStringFingerprint) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/SpoofDeviceDimensionsPatch;" - - override fun execute(context: BytecodeContext) { - DeviceDimensionsModelToStringFingerprint.resultOrThrow().let { result -> - result.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } - .addInstructions( - 1, // Add after super call. - mapOf( - 1 to "MinHeightOrWidth", // p1 = min height - 2 to "MaxHeightOrWidth", // p2 = max height - 3 to "MinHeightOrWidth", // p3 = min width - 4 to "MaxHeightOrWidth" // p4 = max width - ).map { (parameter, method) -> - """ - invoke-static { p$parameter }, $INTEGRATIONS_CLASS_DESCRIPTOR->get$method(I)I - move-result p$parameter - """ - }.joinToString("\n") { it } - ) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", - "SETTINGS: SPOOF_DEVICE_DIMENSIONS" - ) - ) - - SettingsPatch.updatePatchStatus("Spoof device dimensions") - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryBytecodePatch.kt index 77f7dee2a..6eee7aa60 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryBytecodePatch.kt @@ -8,7 +8,6 @@ import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerp import app.revanced.patches.youtube.misc.tracking.fingerprints.ShareLinkFormatterFingerprint import app.revanced.patches.youtube.misc.tracking.fingerprints.SystemShareLinkFormatterFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @@ -55,17 +54,5 @@ object SanitizeUrlQueryBytecodePatch : BaseSanitizeUrlQueryPatch( } } } - - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "SETTINGS: SANITIZE_SHARING_LINKS" - ) - ) - - SettingsPatch.updatePatchStatus("Sanitize sharing links") } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt index fa989eb11..bf3bb6647 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt @@ -26,6 +26,6 @@ object SanitizeUrlQueryPatch : BaseResourcePatch( ) ) - SettingsPatch.updatePatchStatus("Sanitize sharing links") + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/updatescreen/UpdateScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/updatescreen/UpdateScreenPatch.kt index c07ce1da1..fde6f046a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/updatescreen/UpdateScreenPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/updatescreen/UpdateScreenPatch.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patches.youtube.misc.updatescreen.fingerprints.AppBlockingCheckResultToStringFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow @@ -18,9 +17,6 @@ object UpdateScreenPatch : BaseBytecodePatch( compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf(AppBlockingCheckResultToStringFingerprint) ) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/UpdateScreenPatch;" - override fun execute(context: BytecodeContext) { AppBlockingCheckResultToStringFingerprint.resultOrThrow().mutableClass.methods.first { method -> MethodUtil.isConstructor(method) @@ -30,6 +26,6 @@ object UpdateScreenPatch : BaseBytecodePatch( "const/4 p1, 0x0" ) - SettingsPatch.updatePatchStatus("Disable update screen") + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/label/NavigationLabelPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/label/NavigationLabelPatch.kt deleted file mode 100644 index 4a33c4946..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/label/NavigationLabelPatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.youtube.navigation.label - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.navigation.label.fingerprints.PivotBarSetTextFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object NavigationLabelPatch : BaseBytecodePatch( - name = "Hide navigation label", - description = "Adds an option to hide navigation bar labels.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(PivotBarSetTextFingerprint) -) { - override fun execute(context: BytecodeContext) { - - PivotBarSetTextFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = getTargetIndexWithMethodReferenceName("setText") - val targetRegister = getInstruction(targetIndex).registerC - - addInstruction( - targetIndex, - "invoke-static {v$targetRegister}, $NAVIGATION_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V" - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: NAVIGATION_SETTINGS", - "SETTINGS: HIDE_NAVIGATION_LABEL" - ) - ) - - SettingsPatch.updatePatchStatus("Hide navigation label") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt deleted file mode 100644 index 4ce769828..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.youtube.navigation.navigationbuttons - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.AutoMotiveFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object NavigationButtonsPatch : BaseBytecodePatch( - name = "Hide navigation buttons", - description = "Adds options to hide and change navigation buttons (such as the Shorts button).", - dependencies = setOf( - SettingsPatch::class, - NavigationBarHookPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(AutoMotiveFingerprint) -) { - override fun execute(context: BytecodeContext) { - - /** - * Switch create button with notifications button - */ - AutoMotiveFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = getStringInstructionIndex("Android Automotive") - 1 - val register = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z - move-result v$register - """ - ) - } - } - - // Hook navigation button created, in order to hide them. - NavigationBarHookPatch.hookNavigationButtonCreated(NAVIGATION_CLASS_DESCRIPTOR) - - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: NAVIGATION_SETTINGS", - "SETTINGS: HIDE_NAVIGATION_BUTTONS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide navigation buttons") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/TabletNavigationBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/TabletNavigationBarPatch.kt deleted file mode 100644 index 62b1fc63b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/tabletnavbar/TabletNavigationBarPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.youtube.navigation.tabletnavbar - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.fingerprint.MethodFingerprintResult -import app.revanced.patches.youtube.navigation.tabletnavbar.fingerprints.PivotBarChangedFingerprint -import app.revanced.patches.youtube.navigation.tabletnavbar.fingerprints.PivotBarStyleFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object TabletNavigationBarPatch : BaseBytecodePatch( - name = "Enable tablet navigation bar", - description = "Adds an option to enable the tablet navigation bar.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - PivotBarChangedFingerprint, - PivotBarStyleFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - arrayOf( - PivotBarChangedFingerprint, - PivotBarStyleFingerprint - ).forEach { - it.resultOrThrow().insertHook() - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: NAVIGATION_SETTINGS", - "SETTINGS: ENABLE_TABLET_NAVIGATION_BAR" - ) - ) - - SettingsPatch.updatePatchStatus("Enable tablet navigation bar") - - } - - private fun MethodFingerprintResult.insertHook() { - val targetIndex = scanResult.patternScanResult!!.startIndex + 1 - val register = - mutableMethod.getInstruction(targetIndex).registerA - - mutableMethod.addInstructions( - targetIndex + 1, """ - invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->enableTabletNavBar(Z)Z - move-result v$register - """ - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/AlwaysRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/AlwaysRepeatPatch.kt deleted file mode 100644 index f681105b7..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/AlwaysRepeatPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.youtube.overlaybutton.alwaysrepeat - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patches.youtube.overlaybutton.alwaysrepeat.fingerprints.AutoNavInformerFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.util.getTargetIndexReversed -import app.revanced.util.getWalkerMethod -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -object AlwaysRepeatPatch : BytecodePatch( - setOf(AutoNavInformerFingerprint) -) { - override fun execute(context: BytecodeContext) { - - AutoNavInformerFingerprint.resultOrThrow().let { - val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex) - walkerMethod.apply { - val index = getTargetIndexReversed(Opcode.IGET_BOOLEAN) - val register = getInstruction(index).registerA - - addInstructions( - index + 1, """ - invoke-static {v$register}, $UTILS_PATH/AlwaysRepeatPatch;->enableAlwaysRepeat(Z)Z - move-result v$register - """ - ) - } - } - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/fingerprints/AutoNavInformerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/fingerprints/AutoNavInformerFingerprint.kt deleted file mode 100644 index c1a629f2c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/alwaysrepeat/fingerprints/AutoNavInformerFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.overlaybutton.alwaysrepeat.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SettingsBooleanTimeRangeDialog -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object AutoNavInformerFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L"), - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.XOR_INT_2ADDR - ), - literalSupplier = { SettingsBooleanTimeRangeDialog } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/DownloadButtonHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/DownloadButtonHookPatch.kt deleted file mode 100644 index e56a01fd7..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/DownloadButtonHookPatch.kt +++ /dev/null @@ -1,32 +0,0 @@ -package app.revanced.patches.youtube.overlaybutton.download.hook - -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.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.overlaybutton.download.hook.fingerprints.OfflineVideoEndpointFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch -import app.revanced.util.resultOrThrow - -@Patch(dependencies = [MainActivityResolvePatch::class]) -object DownloadButtonHookPatch : BytecodePatch( - setOf(OfflineVideoEndpointFingerprint) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$UTILS_PATH/HookDownloadButtonPatch;" - override fun execute(context: BytecodeContext) { - OfflineVideoEndpointFingerprint.resultOrThrow().mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static/range {p3 .. p3}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Ljava/lang/String;)Z - move-result v0 - if-eqz v0, :show_native_downloader - return-void - """, ExternalLabel("show_native_downloader", getInstruction(0)) - ) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/DisablePiPPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/DisablePiPPatch.kt deleted file mode 100644 index f235acf8a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/DisablePiPPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.youtube.overlaybutton.download.pip - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patches.youtube.overlaybutton.download.pip.fingerprints.PiPPlaybackFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -/** - * Temporarily disable PiP when the external download button is clicked. - * This patch works independently of the MinimizedPlayback patch. - */ -object DisablePiPPatch : BytecodePatch( - setOf(PiPPlaybackFingerprint) -) { - private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR = - "$INTEGRATIONS_PATH/utils/VideoUtils;" - - override fun execute(context: BytecodeContext) { - PiPPlaybackFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->isPiPAvailable(Z)Z - move-result v$insertRegister - """ - ) - } - } - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/FullscreenButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/FullscreenButtonPatch.kt deleted file mode 100644 index 55714770e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/FullscreenButtonPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.youtube.overlaybutton.fullscreen - -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.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.overlaybutton.fullscreen.fingerprints.FullScreenButtonFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.util.getTargetIndexWithReference -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Patch(dependencies = [SharedResourceIdPatch::class]) -object FullscreenButtonPatch : BytecodePatch( - setOf(FullScreenButtonFingerprint) -) { - override fun execute(context: BytecodeContext) { - - FullScreenButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val viewIndex = getTargetIndexWithReference("Landroid/widget/ImageView;->getResources()Landroid/content/res/Resources;") - val viewRegister = getInstruction(viewIndex).registerC - - addInstructionsWithLabels( - viewIndex, """ - invoke-static {v$viewRegister}, $UTILS_PATH/FullscreenButtonPatch;->hideFullscreenButton(Landroid/widget/ImageView;)Landroid/widget/ImageView; - move-result-object v$viewRegister - if-nez v$viewRegister, :show - return-void - """, ExternalLabel("show", getInstruction(viewIndex)) - ) - } - } - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/buttoncontainer/ButtonContainerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt similarity index 66% rename from src/main/kotlin/app/revanced/patches/youtube/buttomplayer/buttoncontainer/ButtonContainerPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt index 29f1f78d0..a821caf78 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/buttoncontainer/ButtonContainerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.buttomplayer.buttoncontainer +package app.revanced.patches.youtube.player.action import app.revanced.patcher.data.ResourceContext import app.revanced.patches.shared.litho.LithoFilterPatch @@ -8,9 +8,9 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.patch.BaseResourcePatch @Suppress("unused") -object ButtonContainerPatch : BaseResourcePatch( - name = "Hide button container", - description = "Adds options to hide action buttons below the video player.", +object ActionButtonsPatch : BaseResourcePatch( + name = "Hide action buttons", + description = "Adds options to hide action buttons under videos.", dependencies = setOf( LithoFilterPatch::class, SettingsPatch::class @@ -18,7 +18,7 @@ object ButtonContainerPatch : BaseResourcePatch( compatiblePackages = COMPATIBLE_PACKAGE, ) { private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ButtonsFilter;" + "$COMPONENTS_PATH/ActionButtonsFilter;" override fun execute(context: ResourceContext) { LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) @@ -28,12 +28,11 @@ object ButtonContainerPatch : BaseResourcePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: BOTTOM_PLAYER_SETTINGS", - "SETTINGS: BUTTON_CONTAINER" + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: HIDE_ACTION_BUTTONS" ) ) - SettingsPatch.updatePatchStatus("Hide button container") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/AmbientModeSwitchPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/AmbientModeSwitchPatch.kt similarity index 64% rename from src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/AmbientModeSwitchPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/AmbientModeSwitchPatch.kt index fb19cc843..5e95760bb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/AmbientModeSwitchPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/AmbientModeSwitchPatch.kt @@ -1,14 +1,12 @@ -package app.revanced.patches.youtube.misc.ambientmode +package app.revanced.patches.youtube.player.ambientmode import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.misc.ambientmode.fingerprints.AmbientModeInFullscreenFingerprint -import app.revanced.patches.youtube.misc.ambientmode.fingerprints.PowerSaveModeFingerprint +import app.revanced.patches.youtube.player.ambientmode.fingerprints.AmbientModeInFullscreenFingerprint +import app.revanced.patches.youtube.player.ambientmode.fingerprints.PowerSaveModeFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getTargetIndexWithMethodReferenceNameReversed import app.revanced.util.literalInstructionBooleanHook @@ -18,7 +16,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") object AmbientModeSwitchPatch : BaseBytecodePatch( - name = "Ambient mode switch", + name = "Ambient mode control", description = "Adds an option to bypass the restrictions of ambient mode or disable it completely.", dependencies = setOf(SettingsPatch::class), compatiblePackages = COMPATIBLE_PACKAGE, @@ -29,6 +27,8 @@ object AmbientModeSwitchPatch : BaseBytecodePatch( ) { override fun execute(context: BytecodeContext) { + // region patch for bypass ambient mode restrictions + PowerSaveModeFingerprint.resultOrThrow().let { it.mutableMethod.apply { val powerSaveModePrimaryIndex = getTargetIndexWithMethodReferenceNameReversed("isPowerSaveMode") @@ -38,38 +38,39 @@ object AmbientModeSwitchPatch : BaseBytecodePatch( powerSaveModePrimaryIndex, powerSaveModeSecondaryIndex ).forEach { index -> - hook(index) + val register = getInstruction(index + 1).registerA + + addInstructions( + index + 2, """ + invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->bypassAmbientModeRestrictions(Z)Z + move-result v$register + """ + ) } } } + // endregion + + // region patch for disable ambient mode in fullscreen + AmbientModeInFullscreenFingerprint.literalInstructionBooleanHook( 45389368, - "$FULLSCREEN_CLASS_DESCRIPTOR->disableAmbientMode()Z" + "$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z" ) + // endregion + /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: FULLSCREEN_SETTINGS", - "SETTINGS: AMBIENT_MODE_SWITCH" + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: AMBIENT_MODE_CONTROLS" ) ) - SettingsPatch.updatePatchStatus("Ambient mode switch") - - } - - private fun MutableMethod.hook(index: Int) { - val register = getInstruction(index + 1).registerA - - addInstructions( - index + 2, """ - invoke-static {v$register}, $MISC_PATH/AmbientModePatch;->bypassPowerSaveModeRestrictions(Z)Z - move-result v$register - """ - ) + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt similarity index 74% rename from src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt index ae0d3ab36..c232564e7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/AmbientModeInFullscreenFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.ambientmode.fingerprints +package app.revanced.patches.youtube.player.ambientmode.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/PowerSaveModeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/PowerSaveModeFingerprint.kt similarity index 94% rename from src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/PowerSaveModeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/PowerSaveModeFingerprint.kt index 4df39ad3b..23f91268e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/ambientmode/fingerprints/PowerSaveModeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/ambientmode/fingerprints/PowerSaveModeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.ambientmode.fingerprints +package app.revanced.patches.youtube.player.ambientmode.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/autoplaybutton/AutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/autoplaybutton/AutoplayButtonPatch.kt deleted file mode 100644 index 2f75aee10..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/autoplaybutton/AutoplayButtonPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtube.player.autoplaybutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavPreviewStub -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VideoZoomIndicatorLayout -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object AutoplayButtonPatch : BaseBytecodePatch( - name = "Hide autoplay button", - description = "Adds an option to hide the autoplay button in the video player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(LayoutConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - - LayoutConstructorFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val dummyRegister = - getInstruction(getStringInstructionIndex("1.0x")).registerA - val insertIndex = getWideLiteralInstructionIndex(AutoNavPreviewStub) - val jumpIndex = getWideLiteralInstructionIndex(VideoZoomIndicatorLayout) - 1 - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideAutoPlayButton()Z - move-result v$dummyRegister - if-nez v$dummyRegister, :hidden - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_AUTOPLAY_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide autoplay button") - - } -} - diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/buttons/PlayerButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/PlayerButtonsPatch.kt new file mode 100644 index 000000000..8f0c532e4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/PlayerButtonsPatch.kt @@ -0,0 +1,230 @@ +package app.revanced.patches.youtube.player.buttons + +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.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.player.buttons.fingerprints.FullScreenButtonFingerprint +import app.revanced.patches.youtube.player.buttons.fingerprints.LithoSubtitleButtonConfigFingerprint +import app.revanced.patches.youtube.player.buttons.fingerprints.MusicAppDeeplinkButtonFingerprint +import app.revanced.patches.youtube.player.buttons.fingerprints.MusicAppDeeplinkButtonParentFingerprint +import app.revanced.patches.youtube.player.buttons.fingerprints.PlayerControlsVisibilityModelFingerprint +import app.revanced.patches.youtube.player.buttons.fingerprints.YouTubeControlsOverlaySubtitleButtonFingerprint +import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint +import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsResourcesFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavToggle +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithReference +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c +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.formats.Instruction3rc + +@Suppress("unused") +object PlayerButtonsPatch : BaseBytecodePatch( + name = "Hide player buttons", + description = "Adds an option to hide buttons in the video player.", + dependencies = setOf( + LithoFilterPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + FullScreenButtonFingerprint, + LayoutConstructorFingerprint, + LithoSubtitleButtonConfigFingerprint, + MusicAppDeeplinkButtonParentFingerprint, + YouTubeControlsOverlaySubtitleButtonFingerprint, + PlayerButtonsResourcesFingerprint, + PlayerControlsVisibilityModelFingerprint, + ) +) { + private const val HAS_NEXT = 5 + private const val HAS_PREVIOUS = 6 + + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/CaptionsFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for hide autoplay button + + LayoutConstructorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(AutoNavToggle) + val constRegister = getInstruction(constIndex).registerA + val jumpIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1 + + addInstructionsWithLabels( + constIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideAutoPlayButton()Z + move-result v$constRegister + if-nez v$constRegister, :hidden + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + } + } + + // endregion + + // region patch for hide captions button + + /** + * Added in YouTube v18.31.40 + * + * No exception even if fail to resolve fingerprints. + * For compatibility with YouTube v18.25.40 ~ YouTube v18.30.37. + */ + LithoSubtitleButtonConfigFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCaptionsButton(Z)Z + move-result v$insertRegister + """ + ) + } + } + + YouTubeControlsOverlaySubtitleButtonFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val insertRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCaptionsButton(Landroid/view/View;)V" + ) + } + } + + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + // endregion + + // region patch for hide collapse button + + PlayerButtonsResourcesFingerprint.resultOrThrow().mutableClass.methods.forEach { method -> + method.apply { + var jumpInstruction = true + + implementation!!.instructions.forEachIndexed { index, instructions -> + val definedInstruction = instructions as? BuilderInstruction35c + + if (instructions.opcode == Opcode.INVOKE_VIRTUAL + && definedInstruction?.reference.toString().contains("setVisibility")) { + val viewRegister = definedInstruction?.registerC + val visibilityRegister = definedInstruction?.registerD + + jumpInstruction = !jumpInstruction + if (jumpInstruction) return@forEachIndexed + + replaceInstruction( + index, + "invoke-static {v$viewRegister, v$visibilityRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCollapseButton(Landroid/view/View;I)V" + ) + } + } + } + } + + // endregion + + // region patch for hide fullscreen button + + FullScreenButtonFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val viewIndex = getTargetIndexWithReference("Landroid/widget/ImageView;->getResources()Landroid/content/res/Resources;") + val viewRegister = getInstruction(viewIndex).registerC + + addInstructionsWithLabels( + viewIndex, """ + invoke-static {v$viewRegister}, $PLAYER_CLASS_DESCRIPTOR->hideFullscreenButton(Landroid/widget/ImageView;)Landroid/widget/ImageView; + move-result-object v$viewRegister + if-nez v$viewRegister, :show + return-void + """, ExternalLabel("show", getInstruction(viewIndex)) + ) + } + } + + // endregion + + // region patch for hide previous and next button + + PlayerControlsVisibilityModelFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val callIndex = getTargetIndex(Opcode.INVOKE_DIRECT_RANGE) + val callInstruction = getInstruction(callIndex) + + val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT + val hasPreviousParameterRegister = callInstruction.startRegister + HAS_PREVIOUS + + addInstructions( + callIndex, """ + invoke-static { v$hasNextParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z + move-result v$hasNextParameterRegister + invoke-static { v$hasPreviousParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z + move-result v$hasPreviousParameterRegister + """ + ) + } + } + + // endregion + + // region patch for hide youtube music button + + MusicAppDeeplinkButtonFingerprint.resolve( + context, + MusicAppDeeplinkButtonParentFingerprint.resultOrThrow().mutableClass + ) + MusicAppDeeplinkButtonFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, + """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideMusicButton()Z + move-result v0 + if-nez v0, :hidden + """, + ExternalLabel("hidden", getInstruction(implementation!!.instructions.size - 1)) + ) + } + } + + // endregion + + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "PREFERENCE_SCREENS: PLAYER_BUTTONS", + "SETTINGS: HIDE_PLAYER_BUTTONS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } +} + diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/fingerprints/FullScreenButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/FullScreenButtonFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/fingerprints/FullScreenButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/FullScreenButtonFingerprint.kt index ad9382780..91d6d1604 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/fullscreen/fingerprints/FullScreenButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/FullScreenButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.overlaybutton.fullscreen.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/LithoSubtitleButtonConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/LithoSubtitleButtonConfigFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/LithoSubtitleButtonConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/LithoSubtitleButtonConfigFingerprint.kt index c6a20c2a3..98eaaffa6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/LithoSubtitleButtonConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/LithoSubtitleButtonConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.captionsbutton.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonFingerprint.kt index 661d98654..12f91dd3d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.musicbutton.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt index ced9a4d3f..284da3ce8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/MusicAppDeeplinkButtonParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.musicbutton.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.MusicAppDeeplinkButtonView import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/fingerprints/PlayerControlsVisibilityModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/fingerprints/PlayerControlsVisibilityModelFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt index f4efdb6bf..c126ce167 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/fingerprints/PlayerControlsVisibilityModelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.previousnextbutton.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt similarity index 77% rename from src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt index e1782db2f..12f55734b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/buttons/fingerprints/YouTubeControlsOverlaySubtitleButtonFingerprint.kt @@ -1,7 +1,7 @@ -package app.revanced.patches.youtube.player.captionsbutton.fingerprints +package app.revanced.patches.youtube.player.buttons.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YoutubeControlsOverlaySubtitleButton +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YouTubeControlsOverlaySubtitleButton import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags @@ -14,5 +14,5 @@ import com.android.tools.smali.dexlib2.AccessFlags internal object YouTubeControlsOverlaySubtitleButtonFingerprint : LiteralValueFingerprint( returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - literalSupplier = { YoutubeControlsOverlaySubtitleButton } + literalSupplier = { YouTubeControlsOverlaySubtitleButton } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/CaptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/CaptionsButtonPatch.kt deleted file mode 100644 index 189f60c22..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/captionsbutton/CaptionsButtonPatch.kt +++ /dev/null @@ -1,86 +0,0 @@ -package app.revanced.patches.youtube.player.captionsbutton - -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.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.player.captionsbutton.fingerprints.LithoSubtitleButtonConfigFingerprint -import app.revanced.patches.youtube.player.captionsbutton.fingerprints.YouTubeControlsOverlaySubtitleButtonFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object CaptionsButtonPatch : BaseBytecodePatch( - name = "Hide captions button", - description = "Adds an option to hide the captions button in the video player.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - LithoSubtitleButtonConfigFingerprint, - YouTubeControlsOverlaySubtitleButtonFingerprint - ) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/CaptionsFilter;" - - override fun execute(context: BytecodeContext) { - - /** - * Added in YouTube v18.31.40 - * - * No exception even if fail to resolve fingerprints. - * For compatibility with YouTube v18.25.40 ~ YouTube v18.30.37. - */ - LithoSubtitleButtonConfigFingerprint.result?.let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCaptionsButton(Z)Z - move-result v$insertRegister - """ - ) - } - } - - YouTubeControlsOverlaySubtitleButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val insertRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCaptionsButton(Landroid/view/View;)V" - ) - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_CAPTIONS_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide captions button") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/collapsebutton/CollapseButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/collapsebutton/CollapseButtonPatch.kt deleted file mode 100644 index 2916d2f35..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/collapsebutton/CollapseButtonPatch.kt +++ /dev/null @@ -1,70 +0,0 @@ -package app.revanced.patches.youtube.player.collapsebutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsResourcesFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.findMutableMethodOf -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c - -@Suppress("unused") -object CollapseButtonPatch : BaseBytecodePatch( - name = "Hide collapse button", - description = "Adds an option to hide the collapse button in the video player.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(PlayerButtonsResourcesFingerprint) -) { - override fun execute(context: BytecodeContext) { - - PlayerButtonsResourcesFingerprint.resultOrThrow().mutableClass.apply { - for (method in methods) { - findMutableMethodOf(method).apply { - var jumpInstruction = true - - implementation!!.instructions.forEachIndexed { index, instructions -> - if (instructions.opcode == Opcode.INVOKE_VIRTUAL) { - val definedInstruction = (instructions as? BuilderInstruction35c) - - if (definedInstruction?.reference.toString() == - "Landroid/view/View;->setVisibility(I)V" - ) { - - jumpInstruction = !jumpInstruction - if (jumpInstruction) return@forEachIndexed - - val firstRegister = definedInstruction?.registerC - val secondRegister = definedInstruction?.registerD - - addInstructions( - index, """ - invoke-static {v$firstRegister, v$secondRegister}, $PLAYER_CLASS_DESCRIPTOR->hidePlayerButton(Landroid/view/View;I)I - move-result v$secondRegister - """ - ) - } - } - } - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_COLLAPSE_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide collapse button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/CommentComponentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/comments/CommentsComponentPatch.kt similarity index 60% rename from src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/CommentComponentPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/comments/CommentsComponentPatch.kt index 2370ba394..c7d10d80c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/CommentComponentPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/comments/CommentsComponentPatch.kt @@ -1,16 +1,16 @@ -package app.revanced.patches.youtube.buttomplayer.comment +package app.revanced.patches.youtube.player.comments 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.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.buttomplayer.comment.fingerprints.ShortsLiveStreamEmojiPickerOnClickListenerFingerprint -import app.revanced.patches.youtube.buttomplayer.comment.fingerprints.ShortsLiveStreamEmojiPickerOpacityFingerprint -import app.revanced.patches.youtube.buttomplayer.comment.fingerprints.ShortsLiveStreamThanksFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.BOTTOM_PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOnClickListenerFingerprint +import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOpacityFingerprint +import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamThanksFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getTargetIndex @@ -23,8 +23,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") -object CommentComponentPatch : BaseBytecodePatch( - name = "Hide comment component", +object CommentsComponentPatch : BaseBytecodePatch( + name = "Hide comments component", description = "Adds options to hide components related to comments.", dependencies = setOf( LithoFilterPatch::class, @@ -41,6 +41,8 @@ object CommentComponentPatch : BaseBytecodePatch( "$COMPONENTS_PATH/CommentsFilter;" override fun execute(context: BytecodeContext) { + // region patch for emoji picker button in shorts + ShortsLiveStreamEmojiPickerOpacityFingerprint.resultOrThrow().let { it.mutableMethod.apply { val insertIndex = implementation!!.instructions.size - 1 @@ -48,13 +50,16 @@ object CommentComponentPatch : BaseBytecodePatch( addInstruction( insertIndex, - "invoke-static {v$insertRegister}, $BOTTOM_PLAYER_CLASS_DESCRIPTOR->changeEmojiPickerOpacity(Landroid/widget/ImageView;)V" + "invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->changeEmojiPickerOpacity(Landroid/widget/ImageView;)V" ) } } - ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let { parentResult -> - parentResult.mutableMethod.apply { + val shortsLiveStreamEmojiPickerOnClickListenerResult = + ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow() + + shortsLiveStreamEmojiPickerOnClickListenerResult.let { + it.mutableMethod.apply { val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492) val emojiPickerOnClickListenerIndex = getTargetIndex(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT) val emojiPickerOnClickListenerMethod = getWalkerMethod(context, emojiPickerOnClickListenerIndex) @@ -65,33 +70,35 @@ object CommentComponentPatch : BaseBytecodePatch( addInstructions( insertIndex, """ - invoke-static {v$insertRegister}, $BOTTOM_PLAYER_CLASS_DESCRIPTOR->disableEmojiPickerOnClickListener(Ljava/lang/Object;)Ljava/lang/Object; + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->disableEmojiPickerOnClickListener(Ljava/lang/Object;)Ljava/lang/Object; move-result-object v$insertRegister """ ) } } + } - ShortsLiveStreamThanksFingerprint.also { - it.resolve( - context, - parentResult.classDef + // endregion + + // region patch for thanks button in shorts + + ShortsLiveStreamThanksFingerprint.resolve(context, shortsLiveStreamEmojiPickerOnClickListenerResult.classDef) + ShortsLiveStreamThanksFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val insertInstruction = getInstruction(insertIndex) + + addInstructions( + insertIndex,""" + invoke-static { v${insertInstruction.registerC}, v${insertInstruction.registerD} }, $PLAYER_CLASS_DESCRIPTOR->hideThanksButton(Landroid/view/View;I)I + move-result v${insertInstruction.registerD} + """ ) - }.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - val insertInstruction = getInstruction(insertIndex) - - addInstructions( - insertIndex,""" - invoke-static { v${insertInstruction.registerC}, v${insertInstruction.registerD} }, $BOTTOM_PLAYER_CLASS_DESCRIPTOR->hideThanksButton(Landroid/view/View;I)I - move-result v${insertInstruction.registerD} - """ - ) - } } } + // endregion + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) /** @@ -99,12 +106,11 @@ object CommentComponentPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: BOTTOM_PLAYER_SETTINGS", - "SETTINGS: COMMENT_COMPONENTS" + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: HIDE_COMMENTS_COMPONENTS" ) ) - SettingsPatch.updatePatchStatus("Hide comment component") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt index 29a7efda8..146415068 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.buttomplayer.comment.fingerprints +package app.revanced.patches.youtube.player.comments.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt index adf3522f5..d2c3d3fd5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamEmojiPickerOpacityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.buttomplayer.comment.fingerprints +package app.revanced.patches.youtube.player.comments.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.EmojiPickerIcon diff --git a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamThanksFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamThanksFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamThanksFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamThanksFingerprint.kt index ac70ba220..0907c266a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/buttomplayer/comment/fingerprints/ShortsLiveStreamThanksFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/comments/fingerprints/ShortsLiveStreamThanksFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.buttomplayer.comment.fingerprints +package app.revanced.patches.youtube.player.comments.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt new file mode 100644 index 000000000..89ee04ffa --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -0,0 +1,402 @@ +package app.revanced.patches.youtube.player.components + +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.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.player.components.fingerprints.CrowdfundingBoxFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.EngagementPanelControllerFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.FilmStripOverlayConfigFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.FilmStripOverlayInteractionFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.FilmStripOverlayParentFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.FilmStripOverlayPreviewFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.InfoCardsIncognitoFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.LayoutCircleFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.LayoutIconFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.LayoutVideoFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.RestoreSlideToSeekBehaviorFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.SeekEduContainerFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.SpeedOverlayFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.SuggestedActionsFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.WatermarkFingerprint +import app.revanced.patches.youtube.player.components.fingerprints.WatermarkParentFingerprint +import app.revanced.patches.youtube.utils.controlsoverlay.ControlsOverlayConfigPatch +import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint +import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.SuggestedVideoEndScreenPatch +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FadeDurationFast +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ScrimOverlay +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SeekUndoEduOverlayStub +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexReversed +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +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.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction + +@Suppress("unused") +object PlayerComponentsPatch : BaseBytecodePatch( + name = "Player components", + description = "Adds options to hide or change components related to player.", + dependencies = setOf( + ControlsOverlayConfigPatch::class, + LithoFilterPatch::class, + PlayerTypeHookPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class, + SuggestedVideoEndScreenPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + CrowdfundingBoxFingerprint, + EngagementPanelControllerFingerprint, + FilmStripOverlayParentFingerprint, + InfoCardsIncognitoFingerprint, + LayoutCircleFingerprint, + LayoutIconFingerprint, + LayoutVideoFingerprint, + RestoreSlideToSeekBehaviorFingerprint, + SeekEduContainerFingerprint, + SpeedOverlayFingerprint, + SuggestedActionsFingerprint, + WatermarkParentFingerprint, + YouTubeControlsOverlayFingerprint, + ) +) { + private const val PLAYER_COMPONENTS_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/PlayerComponentsFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for custom player overlay opacity + + YouTubeControlsOverlayFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(ScrimOverlay) + val targetIndex = getTargetIndex(constIndex, Opcode.CHECK_CAST) + val targetParameter = getInstruction(targetIndex).reference + val targetRegister = getInstruction(targetIndex).registerA + + if (!targetParameter.toString().endsWith("Landroid/widget/ImageView;")) + throw PatchException("Method signature parameter did not match: $targetParameter") + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->changePlayerOpacity(Landroid/widget/ImageView;)V" + ) + } + } + + // endregion + + // region patch for disable auto player popup panels + + EngagementPanelControllerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->disableAutoPlayerPopupPanels()Z + move-result v0 + if-eqz v0, :shown + # The type of the fourth parameter is boolean. + if-eqz p4, :shown + const/4 v0, 0x0 + return-object v0 + """, ExternalLabel("shown", getInstruction(0)) + ) + } + } + + // endregion + + // region patch for disable speed overlay + + mapOf( + RestoreSlideToSeekBehaviorFingerprint to 45411329, + SpeedOverlayFingerprint to 45411330 + ).forEach { (fingerprint, literal) -> + fingerprint.literalInstructionBooleanHook( + literal, + "$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z" + ) + } + + // endregion + + // region patch for hide channel watermark + + WatermarkFingerprint.resolve( + context, + WatermarkParentFingerprint.resultOrThrow().classDef + ) + WatermarkFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val register = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->hideChannelWatermark(Z)Z + move-result v$register + """ + ) + } + } + + // endregion + + // region patch for hide crowdfunding box + + CrowdfundingBoxFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val register = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->hideCrowdfundingBox(Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide end screen cards + + listOf( + LayoutCircleFingerprint, + LayoutIconFingerprint, + LayoutVideoFingerprint + ).forEach{ fingerprint -> + fingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val viewRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex + 1, + "invoke-static { v$viewRegister }, $PLAYER_CLASS_DESCRIPTOR->hideEndScreenCards(Landroid/view/View;)V" + ) + } + } + } + + // endregion + + // region patch for hide filmstrip overlay + + FilmStripOverlayParentFingerprint.resultOrThrow().classDef.let { classDef -> + arrayOf( + FilmStripOverlayConfigFingerprint, + FilmStripOverlayInteractionFingerprint, + FilmStripOverlayPreviewFingerprint + ).forEach { fingerprint -> + fingerprint.resolve(context, classDef) + fingerprint.resultOrThrow().mutableMethod.hook() + } + } + + YouTubeControlsOverlayFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(FadeDurationFast) + val constRegister = getInstruction(constIndex).registerA + val insertIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_VIRTUAL) + 1 + val jumpIndex = getTargetIndex(insertIndex, Opcode.GOTO).coerceAtMost(getTargetIndex(insertIndex, Opcode.GOTO_16)) + + val replaceInstruction = getInstruction(insertIndex) + val replaceReference = + getInstruction(insertIndex).reference + + addLiteralValues(insertIndex, jumpIndex - 1) + + addInstructionsWithLabels( + insertIndex + 1, """ + const v$constRegister, $FadeDurationFast + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z + move-result v${replaceInstruction.registerA} + if-nez v${replaceInstruction.registerA}, :hidden + iget-object v${replaceInstruction.registerA}, v${replaceInstruction.registerB}, $replaceReference + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + removeInstruction(insertIndex) + } + } + + // endregion + + // region patch for hide info cards + + InfoCardsIncognitoFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + val targetRegister = + getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideInfoCard(Z)Z + move-result v$targetRegister + """ + ) + } + } + + // endregion + + // region patch for hide seek message + + SeekEduContainerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekMessage()Z + move-result v0 + if-eqz v0, :default + return-void + """, ExternalLabel("default", getInstruction(0)) + ) + } + } + + YouTubeControlsOverlayFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub) + val insertRegister = getInstruction(insertIndex).registerA + + val onClickListenerIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener") + val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1) + + addInstructionsWithLabels( + insertIndex, constComponent + """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekUndoMessage()Z + move-result v$insertRegister + if-nez v$insertRegister, :default + """, ExternalLabel("default", getInstruction(onClickListenerIndex + 1)) + ) + } + } + + // endregion + + // region patch for hide suggested actions + + SuggestedActionsFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideSuggestedActions(Landroid/view/View;)V" + + ) + } + } + + // endregion + + LithoFilterPatch.addFilter(PLAYER_COMPONENTS_FILTER_CLASS_DESCRIPTOR) + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: PLAYER_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } + + private var literalComponent: String = "" + + private fun MutableMethod.addLiteralValues( + startIndex: Int, + endIndex: Int + ) { + for (index in startIndex..endIndex) { + val opcode = getInstruction(index).opcode + if (opcode != Opcode.CONST_16 && opcode != Opcode.CONST_4 && opcode != Opcode.CONST) + continue + + val register = getInstruction(index).registerA + val value = getInstruction(index).wideLiteral.toInt() + + val line = + when (opcode) { + Opcode.CONST_16 -> """ + const/16 v$register, $value + + """.trimIndent() + + Opcode.CONST_4 -> """ + const/4 v$register, $value + + """.trimIndent() + + Opcode.CONST -> """ + const v$register, $value + + """.trimIndent() + + else -> "" + } + + literalComponent += line + } + } + + private fun MutableMethod.hook() { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z + move-result v0 + if-eqz v0, :shown + const/4 v0, 0x0 + return v0 + """, ExternalLabel("shown", getInstruction(0)) + ) + } + + private fun MutableMethod.getConstComponent( + startIndex: Int, + endIndex: Int + ): String { + val constRegister = + getInstruction(endIndex).registerE + + for (index in endIndex downTo startIndex) { + val instruction = getInstruction(index) + if (instruction !is WideLiteralInstruction) + continue + + if ((instruction as OneRegisterInstruction).registerA != constRegister) + continue + + val constValue = (instruction as WideLiteralInstruction).wideLiteral.toInt() + + return "const/16 v$constRegister, $constValue" + } + return "" + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/fingerprints/CrowdfundingBoxFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/CrowdfundingBoxFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/fingerprints/CrowdfundingBoxFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/CrowdfundingBoxFingerprint.kt index 4d6833482..3ef948311 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/crowdfundingbox/fingerprints/CrowdfundingBoxFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/CrowdfundingBoxFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.crowdfundingbox.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DonationCompanion diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/fingerprints/EngagementPanelControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/EngagementPanelControllerFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/fingerprints/EngagementPanelControllerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/EngagementPanelControllerFingerprint.kt index 0957621d6..ffc7e9c97 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/autopopuppanels/fingerprints/EngagementPanelControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/EngagementPanelControllerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.autopopuppanels.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayConfigFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayConfigFingerprint.kt index c781b2b9a..7385f2e3c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.filmstripoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayInteractionFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayInteractionFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayInteractionFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayInteractionFingerprint.kt index 883d0f280..4300660d7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayInteractionFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayInteractionFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.filmstripoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayParentFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayParentFingerprint.kt index 2f2a3abd5..e9fe1dee8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.filmstripoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Scrubbing diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayPreviewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayPreviewFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayPreviewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayPreviewFingerprint.kt index acece8896..db0696dd2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FilmStripOverlayPreviewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/FilmStripOverlayPreviewFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.filmstripoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/infocards/fingerprints/InfoCardsIncognitoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/InfoCardsIncognitoFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/player/infocards/fingerprints/InfoCardsIncognitoFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/InfoCardsIncognitoFingerprint.kt index b1d35a8e4..cdab91cc3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/infocards/fingerprints/InfoCardsIncognitoFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/InfoCardsIncognitoFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.infocards.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutCircleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutCircleFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutCircleFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutCircleFingerprint.kt index 4902a02ef..ee1271910 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutCircleFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutCircleFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.endscreencards.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.EndScreenElementLayoutCircle import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutIconFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutIconFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutIconFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutIconFingerprint.kt index e70f82564..95483245a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutIconFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutIconFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.endscreencards.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.EndScreenElementLayoutIcon import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutVideoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutVideoFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutVideoFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutVideoFingerprint.kt index cdc1186ba..611f98549 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/fingerprints/LayoutVideoFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/LayoutVideoFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.endscreencards.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.EndScreenElementLayoutVideo import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt index e27dac2f0..698e8a439 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/RestoreSlideToSeekBehaviorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.speedoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SeekEduContainerFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduContainerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SeekEduContainerFingerprint.kt index c6cabd70c..7bac8bba3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduContainerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SeekEduContainerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.seekmessage.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.EasySeekEduContainer import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/SpeedOverlayFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SpeedOverlayFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/SpeedOverlayFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SpeedOverlayFingerprint.kt index dd1fc9e7e..a6e4bd821 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/fingerprints/SpeedOverlayFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SpeedOverlayFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.speedoverlay.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/fingerprints/SuggestedActionsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SuggestedActionsFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/fingerprints/SuggestedActionsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SuggestedActionsFingerprint.kt index 740783a4f..626dff9b7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/fingerprints/SuggestedActionsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/SuggestedActionsFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.suggestactions.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SuggestedAction import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkFingerprint.kt index dc1df33ec..78269518f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.watermark.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkParentFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkParentFingerprint.kt index b95c11786..4f1c036c8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/fingerprints/WatermarkParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/fingerprints/WatermarkParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.watermark.fingerprints +package app.revanced.patches.youtube.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/descriptions/DescriptionComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt similarity index 73% rename from src/main/kotlin/app/revanced/patches/youtube/general/descriptions/DescriptionComponentsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt index 313ae030f..dfa35333d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/descriptions/DescriptionComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt @@ -1,13 +1,13 @@ -package app.revanced.patches.youtube.general.descriptions +package app.revanced.patches.youtube.player.descriptions import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.general.descriptions.fingerprints.TextViewComponentFingerprint +import app.revanced.patches.youtube.player.descriptions.fingerprints.TextViewComponentFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getTargetIndexWithMethodReferenceName @@ -32,6 +32,8 @@ object DescriptionComponentsPatch : BaseBytecodePatch( override fun execute(context: BytecodeContext) { + // patch for ‘Expand video description’ and ‘Disable video description interaction’. + // since these patches are still A/B tested, they are classified as 'Experimental flags'. if (SettingsPatch.upward1902) { TextViewComponentFingerprint.resultOrThrow().let { it.mutableMethod.apply { @@ -41,19 +43,21 @@ object DescriptionComponentsPatch : BaseBytecodePatch( replaceInstruction( insertIndex, "invoke-static {v${insertInstruction.registerC}, v${insertInstruction.registerD}}, " + - "$GENERAL_CLASS_DESCRIPTOR->disableDescriptionInteraction(Landroid/widget/TextView;Z)V" + "$PLAYER_CLASS_DESCRIPTOR->disableVideoDescriptionInteraction(Landroid/widget/TextView;Z)V" ) } } - BottomSheetRecyclerViewPatch.injectCall("$GENERAL_CLASS_DESCRIPTOR->onDescriptionPanelCreate(Landroid/support/v7/widget/RecyclerView;)V") + BottomSheetRecyclerViewPatch.injectCall("$PLAYER_CLASS_DESCRIPTOR->onVideoDescriptionCreate(Landroid/support/v7/widget/RecyclerView;)V") /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "SETTINGS: DESCRIPTION_PANEL_INTERACTION" + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: DESCRIPTION_COMPONENTS", + "SETTINGS: DESCRIPTION_INTERACTION" ) ) } @@ -65,12 +69,11 @@ object DescriptionComponentsPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: GENERAL_SETTINGS", + "PREFERENCE_SCREEN: PLAYER", "SETTINGS: DESCRIPTION_COMPONENTS" ) ) - SettingsPatch.updatePatchStatus("Description components") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/descriptions/fingerprints/TextViewComponentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/fingerprints/TextViewComponentFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/general/descriptions/fingerprints/TextViewComponentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/descriptions/fingerprints/TextViewComponentFingerprint.kt index d41170a0f..a791b12b7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/descriptions/fingerprints/TextViewComponentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/fingerprints/TextViewComponentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.descriptions.fingerprints +package app.revanced.patches.youtube.player.descriptions.fingerprints import app.revanced.util.fingerprint.MethodReferenceNameFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/EndScreenCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/EndScreenCardsPatch.kt deleted file mode 100644 index eb76659bc..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/endscreencards/EndScreenCardsPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtube.player.endscreencards - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.player.endscreencards.fingerprints.LayoutCircleFingerprint -import app.revanced.patches.youtube.player.endscreencards.fingerprints.LayoutIconFingerprint -import app.revanced.patches.youtube.player.endscreencards.fingerprints.LayoutVideoFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object EndScreenCardsPatch : BaseBytecodePatch( - name = "Hide end screen cards", - description = "Adds an option to hide suggested video cards at the end of the video in the video player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - LayoutCircleFingerprint, - LayoutIconFingerprint, - LayoutVideoFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - listOf( - LayoutCircleFingerprint, - LayoutIconFingerprint, - LayoutVideoFingerprint - ).forEach{ fingerprint -> - fingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val viewRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex + 1, - "invoke-static { v$viewRegister }, $PLAYER_CLASS_DESCRIPTOR->hideEndScreenCards(Landroid/view/View;)V" - ) - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_END_SCREEN_CARDS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide end screen cards") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/FilmstripOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/FilmstripOverlayPatch.kt deleted file mode 100644 index 567d793fb..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/FilmstripOverlayPatch.kt +++ /dev/null @@ -1,161 +0,0 @@ -package app.revanced.patches.youtube.player.filmstripoverlay - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.player.filmstripoverlay.fingerprints.FilmStripOverlayConfigFingerprint -import app.revanced.patches.youtube.player.filmstripoverlay.fingerprints.FilmStripOverlayInteractionFingerprint -import app.revanced.patches.youtube.player.filmstripoverlay.fingerprints.FilmStripOverlayParentFingerprint -import app.revanced.patches.youtube.player.filmstripoverlay.fingerprints.FilmStripOverlayPreviewFingerprint -import app.revanced.patches.youtube.player.filmstripoverlay.fingerprints.FineScrubbingOverlayFingerprint -import app.revanced.patches.youtube.utils.controlsoverlay.ControlsOverlayConfigPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -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.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction - -@Suppress("unused") -object FilmstripOverlayPatch : BaseBytecodePatch( - name = "Hide filmstrip overlay", - description = "Adds an option to hide filmstrip overlay in the video player.", - dependencies = setOf( - ControlsOverlayConfigPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - FilmStripOverlayParentFingerprint, - FineScrubbingOverlayFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - FilmStripOverlayParentFingerprint.resultOrThrow().classDef.let { classDef -> - arrayOf( - FilmStripOverlayConfigFingerprint, - FilmStripOverlayInteractionFingerprint, - FilmStripOverlayPreviewFingerprint - ).forEach { fingerprint -> - fingerprint.resolve(context, classDef) - fingerprint.resultOrThrow().mutableMethod.injectHook() - } - } - - FineScrubbingOverlayFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - var insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 - val jumpIndex = getTargetIndexUpTo(insertIndex, Opcode.GOTO, Opcode.GOTO_16) - val initialIndex = jumpIndex - 1 - - if (getInstruction(insertIndex).opcode == Opcode.INVOKE_VIRTUAL) - insertIndex++ - - val replaceInstruction = getInstruction(insertIndex) - val replaceReference = - getInstruction(insertIndex).reference - - addLiteralValues(insertIndex, initialIndex) - - addInstructionsWithLabels( - insertIndex + 1, literalComponent + """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z - move-result v${replaceInstruction.registerA} - if-nez v${replaceInstruction.registerA}, :hidden - iget-object v${replaceInstruction.registerA}, v${replaceInstruction.registerB}, $replaceReference - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) - removeInstruction(insertIndex) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: PLAYER_EXPERIMENTAL_FLAGS", - "SETTINGS: HIDE_FILMSTRIP_OVERLAY" - ) - ) - - SettingsPatch.updatePatchStatus("Hide filmstrip overlay") - - } - - private var literalComponent: String = "" - - private fun MutableMethod.addLiteralValues( - startIndex: Int, - endIndex: Int - ) { - for (index in startIndex..endIndex) { - val opcode = getInstruction(index).opcode - if (opcode != Opcode.CONST_16 && opcode != Opcode.CONST_4 && opcode != Opcode.CONST) - continue - - val register = getInstruction(index).registerA - val value = getInstruction(index).wideLiteral.toInt() - - val line = - when (opcode) { - Opcode.CONST_16 -> """ - const/16 v$register, $value - - """.trimIndent() - - Opcode.CONST_4 -> """ - const/4 v$register, $value - - """.trimIndent() - - Opcode.CONST -> """ - const v$register, $value - - """.trimIndent() - - else -> "" - } - - literalComponent += line - } - } - - private fun MutableMethod.getTargetIndexUpTo( - startIndex: Int, - opcode1: Opcode, - opcode2: Opcode - ): Int { - for (index in startIndex until implementation!!.instructions.size) { - if (getInstruction(index).opcode != opcode1 && getInstruction(index).opcode != opcode2) - continue - - return index - } - throw PatchException("Failed to find hook method") - } - - private fun MutableMethod.injectHook() { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z - move-result v0 - if-eqz v0, :shown - const/4 v0, 0x0 - return v0 - """, ExternalLabel("shown", getInstruction(0)) - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FineScrubbingOverlayFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FineScrubbingOverlayFingerprint.kt deleted file mode 100644 index 1891ec8ce..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/filmstripoverlay/fingerprints/FineScrubbingOverlayFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.player.filmstripoverlay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YoutubeControlsOverlay -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object FineScrubbingOverlayFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.IF_NEZ, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, // insert index - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT - ), - literalSupplier = { YoutubeControlsOverlay } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/PlayerFlyoutPanelPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt similarity index 63% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/PlayerFlyoutPanelPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt index d8b39b965..b45f396aa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/PlayerFlyoutPanelPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt @@ -1,13 +1,13 @@ -package app.revanced.patches.youtube.flyoutpanel.player +package app.revanced.patches.youtube.player.flyoutmenu.hide import app.revanced.patcher.data.BytecodeContext import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.flyoutpanel.player.fingerprints.AdvancedQualityBottomSheetFingerprint -import app.revanced.patches.youtube.flyoutpanel.player.fingerprints.CaptionsBottomSheetFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints.AdvancedQualityBottomSheetFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints.CaptionsBottomSheetFingerprint import app.revanced.patches.youtube.utils.fingerprints.QualityMenuViewInflateFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.FLYOUT_PANEL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR 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 @@ -16,9 +16,9 @@ import app.revanced.util.literalInstructionViewHook import app.revanced.util.patch.BaseBytecodePatch @Suppress("unused") -object PlayerFlyoutPanelPatch : BaseBytecodePatch( - name = "Hide player flyout panel", - description = "Adds options to hide player flyout panel components.", +object PlayerFlyoutMenuPatch : BaseBytecodePatch( + name = "Hide player flyout menu", + description = "Adds options to hide player flyout menu components.", dependencies = setOf( LithoFilterPatch::class, PlayerTypeHookPatch::class, @@ -33,10 +33,7 @@ object PlayerFlyoutPanelPatch : BaseBytecodePatch( ) ) { private const val PANELS_FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/PlayerFlyoutPanelsFilter;" - - private const val PANELS_FOOTER_FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/PlayerFlyoutPanelsFooterFilter;" + "$COMPONENTS_PATH/PlayerFlyoutMenuFilter;" override fun execute(context: BytecodeContext) { arrayOf( @@ -44,25 +41,22 @@ object PlayerFlyoutPanelPatch : BaseBytecodePatch( CaptionsBottomSheetFingerprint to "hideFooterCaptions", QualityMenuViewInflateFingerprint to "hideFooterQuality" ).map { (fingerprint, name) -> - fingerprint.literalInstructionViewHook(BottomSheetFooterText, "$FLYOUT_PANEL_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V") + fingerprint.literalInstructionViewHook(BottomSheetFooterText, "$PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V") } LithoFilterPatch.addFilter(PANELS_FILTER_CLASS_DESCRIPTOR) - LithoFilterPatch.addFilter(PANELS_FOOTER_FILTER_CLASS_DESCRIPTOR) /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: FLYOUT_PANEL_SETTINGS", - "SETTINGS: PLAYER_FLYOUT_PANEL_HEADER", - "SETTINGS: PLAYER_FLYOUT_PANEL_ADDITIONAL_SETTINGS_HEADER", - "SETTINGS: HIDE_PLAYER_FLYOUT_PANEL" + "PREFERENCE_SCREEN: PLAYER", + "PREFERENCE_SCREENS: FLYOUT_MENU", + "SETTINGS: HIDE_PLAYER_FLYOUT_MENU" ) ) - SettingsPatch.updatePatchStatus("Hide player flyout panel") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/AdvancedQualityBottomSheetFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/AdvancedQualityBottomSheetFingerprint.kt similarity index 94% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/AdvancedQualityBottomSheetFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/AdvancedQualityBottomSheetFingerprint.kt index cee2b1e26..38a6cde06 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/AdvancedQualityBottomSheetFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/AdvancedQualityBottomSheetFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.player.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VideoQualityBottomSheet diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/CaptionsBottomSheetFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/CaptionsBottomSheetFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/CaptionsBottomSheetFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/CaptionsBottomSheetFingerprint.kt index 9de7d4099..5a1cbf5c5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/player/fingerprints/CaptionsBottomSheetFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/fingerprints/CaptionsBottomSheetFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.player.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/ChangeTogglePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/ChangeTogglePatch.kt similarity index 79% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/ChangeTogglePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/ChangeTogglePatch.kt index 38e831c09..a2753d7de 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/ChangeTogglePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/ChangeTogglePatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle +package app.revanced.patches.youtube.player.flyoutmenu.toggle import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions @@ -7,13 +7,14 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints.AdditionalSettingsConfigFingerprint -import app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints.CinematicLightingFingerprint -import app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints.PlaybackLoopInitFingerprint -import app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints.PlaybackLoopOnClickListenerFingerprint -import app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints.StableVolumeFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.AdditionalSettingsConfigFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.CinematicLightingFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.PiPFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.PlaybackLoopInitFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.PlaybackLoopOnClickListenerFingerprint +import app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints.StableVolumeFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.FLYOUT_PANEL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getStringInstructionIndex import app.revanced.util.getTargetIndex @@ -28,13 +29,14 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @Suppress("unused") object ChangeTogglePatch : BaseBytecodePatch( - name = "Change player flyout panel toggles", + name = "Change player flyout menu toggles", description = "Adds an option to use text toggles instead of switch toggles within the additional settings menu.", dependencies = setOf(SettingsPatch::class), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( AdditionalSettingsConfigFingerprint, CinematicLightingFingerprint, + PiPFingerprint, PlaybackLoopOnClickListenerFingerprint, StableVolumeFingerprint ) @@ -48,12 +50,18 @@ object ChangeTogglePatch : BaseBytecodePatch( val playbackLoopOnClickListenerResult = PlaybackLoopOnClickListenerFingerprint.resultOrThrow() PlaybackLoopInitFingerprint.resolve(context, playbackLoopOnClickListenerResult.classDef) - arrayOf( + var fingerprintArray = arrayOf( CinematicLightingFingerprint, PlaybackLoopInitFingerprint, PlaybackLoopOnClickListenerFingerprint, StableVolumeFingerprint - ).forEach { fingerprint -> + ) + + PiPFingerprint.result?.let { + fingerprintArray += PiPFingerprint + } + + fingerprintArray.forEach { fingerprint -> injectCall(fingerprint, methodToCall) } @@ -62,13 +70,13 @@ object ChangeTogglePatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: FLYOUT_PANEL_SETTINGS", - "SETTINGS: PLAYER_FLYOUT_PANEL_ADDITIONAL_SETTINGS_HEADER", - "SETTINGS: CHANGE_PLAYER_FLYOUT_PANEL_TOGGLE" + "PREFERENCE_SCREEN: PLAYER", + "PREFERENCE_SCREENS: FLYOUT_MENU", + "SETTINGS: CHANGE_PLAYER_FLYOUT_MENU_TOGGLE" ) ) - SettingsPatch.updatePatchStatus("Change player flyout panel toggles") + SettingsPatch.updatePatchStatus(this) } private fun injectCall( @@ -87,7 +95,7 @@ object ChangeTogglePatch : BaseBytecodePatch( addInstructions( referenceIndex + 2, """ - invoke-static {v$insertRegister}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->changeSwitchToggle(Z)Z + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->changeSwitchToggle(Z)Z move-result v$insertRegister """ ) @@ -95,7 +103,7 @@ object ChangeTogglePatch : BaseBytecodePatch( if (fingerprint == CinematicLightingFingerprint) injectCinematicLightingMethod() else - throw PatchException("Target reference'$methodToCall' was not found in ${this.javaClass.simpleName}.") + throw PatchException("Target reference was not found in ${fingerprint.javaClass.simpleName}.") } } } @@ -136,18 +144,18 @@ object ChangeTogglePatch : BaseBytecodePatch( addInstructionsWithLabels( insertIndex, """ const/4 v$freeRegisterC, 0x1 - invoke-static {v$freeRegisterC}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->changeSwitchToggle(Z)Z + invoke-static {v$freeRegisterC}, $PLAYER_CLASS_DESCRIPTOR->changeSwitchToggle(Z)Z move-result v$freeRegisterC if-nez v$freeRegisterC, :ignore sget-object v$freeRegisterC, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean; if-eq v$freeRegisterC, v$freeRegisterE, :toggle_off const-string v$freeRegisterE, "stable_volume_on" - invoke-static {v$freeRegisterE}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->getToggleString(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$freeRegisterE}, $PLAYER_CLASS_DESCRIPTOR->getToggleString(Ljava/lang/String;)Ljava/lang/String; move-result-object v$freeRegisterE goto :set_string :toggle_off const-string v$freeRegisterE, "stable_volume_off" - invoke-static {v$freeRegisterE}, $FLYOUT_PANEL_CLASS_DESCRIPTOR->getToggleString(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$freeRegisterE}, $PLAYER_CLASS_DESCRIPTOR->getToggleString(Ljava/lang/String;)Ljava/lang/String; move-result-object v$freeRegisterE :set_string iget-object v$freeRegisterC, p0, $iGetObjectPrimaryReference diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt similarity index 72% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt index 0407c310c..9e9e5eeef 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/AdditionalSettingsConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/CinematicLightingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/CinematicLightingFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/CinematicLightingFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/CinematicLightingFingerprint.kt index c2ddbd985..6dec18109 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/CinematicLightingFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/CinematicLightingFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PiPFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PiPFingerprint.kt new file mode 100644 index 000000000..ea748813b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PiPFingerprint.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PiPFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + strings = listOf("menu_item_picture_in_picture"), + customFingerprint = { _, classDef -> + classDef.methods.count() > 5 + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopInitFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopInitFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopInitFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopInitFingerprint.kt index 8e8817af9..dca37520d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopInitFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopInitFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt index 069ffa98c..7f3fcadd9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/PlaybackLoopOnClickListenerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/StableVolumeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/StableVolumeFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/StableVolumeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/StableVolumeFingerprint.kt index 28c536149..dd1c5f1ac 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/flyoutpanel/toggle/fingerprints/StableVolumeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/toggle/fingerprints/StableVolumeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.flyoutpanel.toggle.fingerprints +package app.revanced.patches.youtube.player.flyoutmenu.toggle.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt new file mode 100644 index 000000000..d31fadd52 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt @@ -0,0 +1,338 @@ +package app.revanced.patches.youtube.player.fullscreen + +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.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.player.fullscreen.fingerprints.BroadcastReceiverFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.ClientSettingEndpointFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.EngagementPanelFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.LandScapeModeConfigFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.OrientationParentFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.OrientationPrimaryFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.OrientationSecondaryFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.QuickActionsElementFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.RelatedEndScreenResultsFingerprint +import app.revanced.patches.youtube.player.fullscreen.fingerprints.VideoPortraitParentFingerprint +import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint +import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavPreviewStub +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenEngagementPanel +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QuickActionsElementContainer +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.getStringInstructionIndex +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWalkerMethod +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import app.revanced.util.updatePatchStatus +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.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction + +@Suppress("unused") +object FullscreenComponentsPatch : BaseBytecodePatch( + name = "Fullscreen components", + description = "Adds options to hide or change components related to fullscreen.", + dependencies = setOf( + LithoFilterPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + BroadcastReceiverFingerprint, + ClientSettingEndpointFingerprint, + EngagementPanelFingerprint, + LandScapeModeConfigFingerprint, + LayoutConstructorFingerprint, + OrientationParentFingerprint, + QuickActionsElementFingerprint, + RelatedEndScreenResultsFingerprint, + VideoPortraitParentFingerprint, + YouTubeControlsOverlayFingerprint + ) +) { + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/QuickActionFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for disable engagement panel + + EngagementPanelFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val literalIndex = getWideLiteralInstructionIndex(FullScreenEngagementPanel) + val targetIndex = getTargetIndex(literalIndex, Opcode.CHECK_CAST) + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, " + + "$PLAYER_CLASS_DESCRIPTOR->disableEngagementPanels(Landroidx/coordinatorlayout/widget/CoordinatorLayout;)V" + ) + } + } + + LayoutConstructorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getTargetIndexWithMethodReferenceName("addView") + val insertInstruction = getInstruction(insertIndex) + + replaceInstruction( + insertIndex, + "invoke-static { v${insertInstruction.registerC}, v${insertInstruction.registerD} }, " + + "$PLAYER_CLASS_DESCRIPTOR->showVideoTitleSection(Landroid/widget/FrameLayout;Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide autoplay preview + + LayoutConstructorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(AutoNavPreviewStub) + val constRegister = getInstruction(constIndex).registerA + val jumpIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1 + + addInstructionsWithLabels( + constIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideAutoPlayPreview()Z + move-result v$constRegister + if-nez v$constRegister, :hidden + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + } + } + + // endregion + + // region patch for hide related video overlay + + RelatedEndScreenResultsFingerprint.resultOrThrow().let { + it.mutableClass.methods.find { method -> method.parameters == listOf("I", "Z", "I") } + ?.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideRelatedVideoOverlay()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } ?: throw PatchException("Could not find targetMethod") + } + + // endregion + + // region patch for quick actions + + QuickActionsElementFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val containerCalls = implementation!!.instructions.withIndex() + .filter { instruction -> + (instruction.value as? WideLiteralInstruction)?.wideLiteral == QuickActionsElementContainer + } + val constIndex = containerCalls.elementAt(containerCalls.size - 1).index + + val checkCastIndex = getTargetIndex(constIndex, Opcode.CHECK_CAST) + val insertRegister = + getInstruction(checkCastIndex).registerA + + addInstruction( + checkCastIndex + 1, + "invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->setQuickActionMargin(Landroid/widget/FrameLayout;)V" + ) + + addInstruction( + checkCastIndex, + "invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hideQuickActions(Landroid/view/View;)V" + ) + } + } + + context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "QuickActions") + + // endregion + + // region patch for compact control overlay + + YouTubeControlsOverlayFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getTargetIndexWithMethodReferenceName("setFocusableInTouchMode") + val walkerIndex = getTargetIndex(targetIndex, Opcode.INVOKE_STATIC) + + val walkerMethod = getWalkerMethod(context, walkerIndex) + walkerMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val targetRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableCompactControlsOverlay(Z)Z + move-result v$targetRegister + """ + ) + } + } + } + + // endregion + + // region patch for force fullscreen + + ClientSettingEndpointFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val getActivityIndex = getStringInstructionIndex("watch") + 2 + val getActivityReference = + getInstruction(getActivityIndex).reference + val classRegister = + getInstruction(getActivityIndex).registerB + + val watchDescriptorMethodIndex = + getStringInstructionIndex("start_watch_minimized") - 1 + val watchDescriptorRegister = + getInstruction(watchDescriptorMethodIndex).registerD + + addInstructions( + watchDescriptorMethodIndex, """ + invoke-static {v$watchDescriptorRegister}, $PLAYER_CLASS_DESCRIPTOR->forceFullscreen(Z)Z + move-result v$watchDescriptorRegister + """ + ) + + // hooks Activity. + val insertIndex = getStringInstructionIndex("force_fullscreen") + val freeRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + iget-object v$freeRegister, v$classRegister, $getActivityReference + check-cast v$freeRegister, Landroid/app/Activity; + invoke-static {v$freeRegister}, $PLAYER_CLASS_DESCRIPTOR->setWatchDescriptorActivity(Landroid/app/Activity;)V + """ + ) + } + } + + VideoPortraitParentFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val stringIndex = + getStringInstructionIndex("Acquiring NetLatencyActionLogger failed. taskId=") + val invokeIndex = getTargetIndex(stringIndex, Opcode.INVOKE_INTERFACE) + val targetIndex = getTargetIndex(invokeIndex, Opcode.CHECK_CAST) + val targetClass = context + .findClass(getInstruction(targetIndex).reference.toString())!! + .mutableClass + + // add an instruction to check the vertical video + targetClass.methods.find { method -> method.parameters == listOf("I", "I", "Z") } + ?.apply { + addInstruction( + 1, + "invoke-static {p1, p2}, $PLAYER_CLASS_DESCRIPTOR->setVideoPortrait(II)V" + ) + } ?: throw PatchException("Could not find targetMethod") + } + } + + // endregion + + // region patch for disable landscape mode + + OrientationParentFingerprint.resultOrThrow().classDef.let { classDef -> + arrayOf( + OrientationPrimaryFingerprint, + OrientationSecondaryFingerprint + ).forEach { fingerprint -> + fingerprint.resolve(context, classDef) + + fingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val index = it.scanResult.patternScanResult!!.endIndex + val register = getInstruction(index).registerA + + addInstructions( + index + 1, """ + invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->disableLandScapeMode(Z)Z + move-result v$register + """ + ) + } + } + } + } + + // endregion + + // region patch for keep landscape mode + + if (SettingsPatch.upward1842) { + LandScapeModeConfigFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->keepFullscreen(Z)Z + move-result v$insertRegister + """ + ) + } + + BroadcastReceiverFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + val stringIndex = getStringInstructionIndex("android.intent.action.SCREEN_ON") + val insertIndex = getTargetIndex(stringIndex, Opcode.IF_EQZ) + 1 + + addInstruction( + insertIndex, + "invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->setScreenOn()V" + ) + } + } + + SettingsPatch.addPreference( + arrayOf( + "SETTINGS: KEEP_LANDSCAPE_MODE" + ) + ) + } + } + + // endregion + + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: FULLSCREEN_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/BroadcastReceiverFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/BroadcastReceiverFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/BroadcastReceiverFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/BroadcastReceiverFingerprint.kt index e6af2829b..2e27a4477 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/BroadcastReceiverFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/BroadcastReceiverFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/ClientSettingEndpointFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/ClientSettingEndpointFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/ClientSettingEndpointFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/ClientSettingEndpointFingerprint.kt index f48f47596..32e1e3637 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/ClientSettingEndpointFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/ClientSettingEndpointFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.forcefullscreen.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/fingerprints/FullscreenEngagementPanelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/EngagementPanelFingerprint.kt similarity index 62% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/fingerprints/FullscreenEngagementPanelFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/EngagementPanelFingerprint.kt index 7b863d329..fec64cd51 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/fullscreenpanels/fingerprints/FullscreenEngagementPanelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/EngagementPanelFingerprint.kt @@ -1,9 +1,9 @@ -package app.revanced.patches.youtube.fullscreen.fullscreenpanels.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenEngagementPanel import app.revanced.util.fingerprint.LiteralValueFingerprint -internal object FullscreenEngagementPanelFingerprint : LiteralValueFingerprint( +internal object EngagementPanelFingerprint : LiteralValueFingerprint( returnType = "L", parameters = listOf("L"), literalSupplier = { FullScreenEngagementPanel } diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/LandScapeModeConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/LandScapeModeConfigFingerprint.kt similarity index 77% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/LandScapeModeConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/LandScapeModeConfigFingerprint.kt index 02bd1977a..fe1678afd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/LandScapeModeConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/LandScapeModeConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationParentFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationParentFingerprint.kt index 5538ef668..1eb971bc2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationPrimaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationPrimaryFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationPrimaryFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationPrimaryFingerprint.kt index 5e526331a..fbf8b9b9e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationPrimaryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationPrimaryFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationSecondaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationSecondaryFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationSecondaryFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationSecondaryFingerprint.kt index bc2dbb2dd..bc9735ac5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/landscapemode/fingerprints/OrientationSecondaryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/OrientationSecondaryFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.landscapemode.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/fingerprints/QuickActionsElementFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/QuickActionsElementFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/fingerprints/QuickActionsElementFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/QuickActionsElementFingerprint.kt index 14025580f..726b0048f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/fingerprints/QuickActionsElementFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/QuickActionsElementFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.quickactions.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QuickActionsElementContainer diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/fingerprints/EndScreenResultsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/RelatedEndScreenResultsFingerprint.kt similarity index 60% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/fingerprints/EndScreenResultsParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/RelatedEndScreenResultsFingerprint.kt index 0efee2eab..3e0a05da9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/endscreenoverlay/fingerprints/EndScreenResultsParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/RelatedEndScreenResultsFingerprint.kt @@ -1,9 +1,9 @@ -package app.revanced.patches.youtube.fullscreen.endscreenoverlay.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AppRelatedEndScreenResults import app.revanced.util.fingerprint.LiteralValueFingerprint -internal object EndScreenResultsParentFingerprint : LiteralValueFingerprint( +internal object RelatedEndScreenResultsFingerprint : LiteralValueFingerprint( returnType = "V", literalSupplier = { AppRelatedEndScreenResults } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/VideoPortraitParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/VideoPortraitParentFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/VideoPortraitParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/VideoPortraitParentFingerprint.kt index 3539c0352..9c9caf65c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/fullscreen/forcefullscreen/fingerprints/VideoPortraitParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/fingerprints/VideoPortraitParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.fullscreen.forcefullscreen.fingerprints +package app.revanced.patches.youtube.player.fullscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/hapticfeedback/HapticFeedBackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/hapticfeedback/HapticFeedBackPatch.kt index 85853a65d..da02893dd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/hapticfeedback/HapticFeedBackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/hapticfeedback/HapticFeedBackPatch.kt @@ -50,13 +50,12 @@ object HapticFeedBackPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: PLAYER_SETTINGS", + "PREFERENCE_SCREEN: PLAYER", "SETTINGS: DISABLE_HAPTIC_FEEDBACK" ) ) - SettingsPatch.updatePatchStatus("Disable haptic feedback") - + SettingsPatch.updatePatchStatus(this) } private fun MethodFingerprint.injectHook(methodName: String) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/infocards/InfoCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/infocards/InfoCardsPatch.kt deleted file mode 100644 index 373243c7e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/infocards/InfoCardsPatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.player.infocards - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.player.infocards.fingerprints.InfoCardsIncognitoFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object InfoCardsPatch : BaseBytecodePatch( - name = "Hide info cards", - description = "Adds an option to hide info-cards in the video player.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(InfoCardsIncognitoFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/InfoCardsFilter;" - - override fun execute(context: BytecodeContext) { - InfoCardsIncognitoFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex - val targetRegister = - getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideInfoCard(Z)Z - move-result v$targetRegister - """ - ) - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_INFO_CARDS" - ) - ) - - SettingsPatch.updatePatchStatus("Hide info cards") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/MusicButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/MusicButtonPatch.kt deleted file mode 100644 index e5f244362..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/musicbutton/MusicButtonPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.youtube.player.musicbutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.player.musicbutton.fingerprints.MusicAppDeeplinkButtonFingerprint -import app.revanced.patches.youtube.player.musicbutton.fingerprints.MusicAppDeeplinkButtonParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object MusicButtonPatch : BaseBytecodePatch( - name = "Hide music button", - description = "Adds an option to hide the YouTube Music button in the video player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MusicAppDeeplinkButtonParentFingerprint) -) { - override fun execute(context: BytecodeContext) { - - val mutableClass = MusicAppDeeplinkButtonParentFingerprint.resultOrThrow().mutableClass - MusicAppDeeplinkButtonFingerprint.resolve(context, mutableClass) - - MusicAppDeeplinkButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, - """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideMusicButton()Z - move-result v0 - if-nez v0, :hidden - """, - ExternalLabel("hidden", getInstruction(implementation!!.instructions.size - 1)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_YOUTUBE_MUSIC_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide music button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsBytecodePatch.kt new file mode 100644 index 000000000..671c7f5c1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsBytecodePatch.kt @@ -0,0 +1,58 @@ +package app.revanced.patches.youtube.player.overlaybuttons + +import app.revanced.patcher.data.BytecodeContext +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.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.player.overlaybuttons.fingerprints.OfflineVideoEndpointFingerprint +import app.revanced.patches.youtube.player.overlaybuttons.fingerprints.PiPPlaybackFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch +import app.revanced.util.resultOrThrow +import app.revanced.util.updatePatchStatus +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch(dependencies = [MainActivityResolvePatch::class]) +object OverlayButtonsBytecodePatch : BytecodePatch( + setOf( + OfflineVideoEndpointFingerprint, + PiPPlaybackFingerprint + ) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$INTEGRATIONS_PATH/utils/VideoUtils;" + + override fun execute(context: BytecodeContext) { + OfflineVideoEndpointFingerprint.resultOrThrow().mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static/range {p3 .. p3}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Ljava/lang/String;)Z + move-result v0 + if-eqz v0, :show_native_downloader + return-void + """, ExternalLabel("show_native_downloader", getInstruction(0)) + ) + } + + PiPPlaybackFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->getExternalDownloaderLaunchedState(Z)Z + move-result v$insertRegister + """ + ) + } + } + + context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "OverlayButtons") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/general/OverlayButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt similarity index 93% rename from src/main/kotlin/app/revanced/patches/youtube/overlaybutton/general/OverlayButtonsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt index 295c0a24d..77c740015 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/general/OverlayButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt @@ -1,12 +1,9 @@ -package app.revanced.patches.youtube.overlaybutton.general +package app.revanced.patches.youtube.player.overlaybuttons import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption -import app.revanced.patches.youtube.overlaybutton.alwaysrepeat.AlwaysRepeatPatch -import app.revanced.patches.youtube.overlaybutton.download.hook.DownloadButtonHookPatch -import app.revanced.patches.youtube.overlaybutton.download.pip.DisablePiPPatch -import app.revanced.patches.youtube.overlaybutton.fullscreen.FullscreenButtonPatch import app.revanced.patches.youtube.utils.fix.fullscreen.FullscreenButtonViewStubPatch +import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.SuggestedVideoEndScreenPatch import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.OVERLAY_BUTTONS_PATH import app.revanced.patches.youtube.utils.playercontrols.PlayerControlsPatch @@ -24,13 +21,11 @@ object OverlayButtonsPatch : BaseResourcePatch( name = "Overlay buttons", description = "Adds an option to display overlay buttons in the video player.", dependencies = setOf( - AlwaysRepeatPatch::class, - DisablePiPPatch::class, - DownloadButtonHookPatch::class, - FullscreenButtonPatch::class, FullscreenButtonViewStubPatch::class, PlayerControlsPatch::class, SettingsPatch::class, + SuggestedVideoEndScreenPatch::class, + OverlayButtonsBytecodePatch::class, VideoInformationPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE @@ -233,12 +228,12 @@ object OverlayButtonsPatch : BaseResourcePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: OVERLAY_BUTTONS", + "PREFERENCE_SCREEN: PLAYER", + "PREFERENCE_SCREENS: PLAYER_BUTTONS", "SETTINGS: OVERLAY_BUTTONS" ) ) - SettingsPatch.updatePatchStatus("Overlay buttons") - + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/fingerprints/OfflineVideoEndpointFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/OfflineVideoEndpointFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/fingerprints/OfflineVideoEndpointFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/OfflineVideoEndpointFingerprint.kt index 987e0e7d8..185f4cc43 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/hook/fingerprints/OfflineVideoEndpointFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/OfflineVideoEndpointFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.overlaybutton.download.hook.fingerprints +package app.revanced.patches.youtube.player.overlaybuttons.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/fingerprints/PiPPlaybackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/PiPPlaybackFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/fingerprints/PiPPlaybackFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/PiPPlaybackFingerprint.kt index b376fa6ed..04ef6cd29 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/overlaybutton/download/pip/fingerprints/PiPPlaybackFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/fingerprints/PiPPlaybackFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.overlaybutton.download.pip.fingerprints +package app.revanced.patches.youtube.player.overlaybuttons.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/playeroverlay/CustomPlayerOverlayOpacityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/playeroverlay/CustomPlayerOverlayOpacityPatch.kt deleted file mode 100644 index e48765dae..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/playeroverlay/CustomPlayerOverlayOpacityPatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.player.playeroverlay - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ScrimOverlay -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction - -@Suppress("unused") -object CustomPlayerOverlayOpacityPatch : BaseBytecodePatch( - name = "Custom player overlay opacity", - description = "Adds an option to change the opacity of the video player background when player controls are visible.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(YouTubeControlsOverlayFingerprint) -) { - override fun execute(context: BytecodeContext) { - - YouTubeControlsOverlayFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = getWideLiteralInstructionIndex(ScrimOverlay) + 3 - val targetParameter = getInstruction(targetIndex).reference - val targetRegister = getInstruction(targetIndex).registerA - - if (!targetParameter.toString().endsWith("Landroid/widget/ImageView;")) - throw PatchException("Method signature parameter did not match: $targetParameter") - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->changePlayerOpacity(Landroid/widget/ImageView;)V" - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: CUSTOM_PLAYER_OVERLAY_OPACITY" - ) - ) - - SettingsPatch.updatePatchStatus("Custom player overlay opacity") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/PreviousNextButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/PreviousNextButtonPatch.kt deleted file mode 100644 index e45f03687..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/previousnextbutton/PreviousNextButtonPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.youtube.player.previousnextbutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.player.previousnextbutton.fingerprints.PlayerControlsVisibilityModelFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc - -@Suppress("unused") -object PreviousNextButtonPatch : BaseBytecodePatch( - name = "Hide previous next button", - description = "Adds an option to hide the previous and next buttons in the video player.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(PlayerControlsVisibilityModelFingerprint) -) { - private const val HAS_NEXT = 5 - private const val HAS_PREVIOUS = 6 - - private const val INTEGRATIONS_METHOD_REFERENCE = - "$PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z" - - override fun execute(context: BytecodeContext) { - - PlayerControlsVisibilityModelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val callIndex = it.scanResult.patternScanResult!!.endIndex - val callInstruction = getInstruction(callIndex) - - val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT - val hasPreviousParameterRegister = callInstruction.startRegister + HAS_PREVIOUS - - addInstructions( - callIndex, """ - invoke-static { v$hasNextParameterRegister }, $INTEGRATIONS_METHOD_REFERENCE - move-result v$hasNextParameterRegister - invoke-static { v$hasPreviousParameterRegister }, $INTEGRATIONS_METHOD_REFERENCE - move-result v$hasPreviousParameterRegister - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_PREVIOUS_NEXT_BUTTON" - ) - ) - - SettingsPatch.updatePatchStatus("Hide previous next button") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt new file mode 100644 index 000000000..3b93ad8d1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt @@ -0,0 +1,260 @@ +package app.revanced.patches.youtube.player.seekbar + +import app.revanced.patcher.data.BytecodeContext +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.PatchException +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.drawable.DrawableColorPatch +import app.revanced.patches.youtube.player.seekbar.fingerprints.ControlsOverlayStyleFingerprint +import app.revanced.patches.youtube.player.seekbar.fingerprints.SeekbarTappingFingerprint +import app.revanced.patches.youtube.player.seekbar.fingerprints.ShortsSeekbarColorFingerprint +import app.revanced.patches.youtube.player.seekbar.fingerprints.ThumbnailPreviewConfigFingerprint +import app.revanced.patches.youtube.player.seekbar.fingerprints.TimeCounterFingerprint +import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerprint +import app.revanced.patches.youtube.utils.fingerprints.SeekbarFingerprint +import app.revanced.patches.youtube.utils.fingerprints.SeekbarOnDrawFingerprint +import app.revanced.patches.youtube.utils.fingerprints.TotalTimeFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarColorizedBarPlayedColorDark +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarPlayedNotHighlightedColor +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelTimeBarPlayedColor +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts +import app.revanced.patches.youtube.video.information.VideoInformationPatch +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWalkerMethod +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c +import com.android.tools.smali.dexlib2.dexbacked.reference.DexBackedMethodReference +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import org.w3c.dom.Element + +@Suppress("DEPRECATION", "unused") +object SeekbarComponentsPatch : BaseBytecodePatch( + name = "Seekbar components", + description = "Adds options to hide or change components related to player.", + dependencies = setOf( + DrawableColorPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class, + VideoInformationPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + ControlsOverlayStyleFingerprint, + PlayerSeekbarColorFingerprint, + PlayerSeekbarColorFingerprint, + SeekbarFingerprint, + SeekbarTappingFingerprint, + ShortsSeekbarColorFingerprint, + ThumbnailPreviewConfigFingerprint, + TotalTimeFingerprint + ) +) { + override fun execute(context: BytecodeContext) { + + // region patch for enable seekbar tapping patch + + SeekbarTappingFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val tapSeekIndex = it.scanResult.patternScanResult!!.startIndex + 1 + val tapSeekReference = getInstruction(tapSeekIndex).reference + val tapSeekClass = + context + .findClass((tapSeekReference as DexBackedMethodReference).definingClass)!! + .mutableClass + val tapSeekMethods = mutableMapOf() + + for (method in tapSeekClass.methods) { + if (method.implementation == null) + continue + + val instructions = method.implementation!!.instructions + // here we make sure we actually find the method because it has more than 7 instructions + if (instructions.count() != 10) + continue + + // we know that the 7th instruction has the opcode CONST_4 + val instruction = instructions.elementAt(6) + if (instruction.opcode != Opcode.CONST_4) + continue + + // the literal for this instruction has to be either 1 or 2 + val literal = (instruction as NarrowLiteralInstruction).narrowLiteral + + // method founds + if (literal == 1) + tapSeekMethods["P"] = method + else if (literal == 2) + tapSeekMethods["O"] = method + } + + val pMethod = tapSeekMethods["P"] + ?: throw PatchException("pMethod not found") + val oMethod = tapSeekMethods["O"] + ?: throw PatchException("oMethod not found") + + val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSeekbarTapping()Z + move-result v0 + if-eqz v0, :disabled + invoke-virtual { p0, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V + invoke-virtual { p0, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V + """, ExternalLabel("disabled", getInstruction(insertIndex)) + ) + } + } + + // endregion + + // region patch for append time stamps information + + TotalTimeFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1 + val charSequenceRegister = getInstruction(charSequenceIndex).registerA + val textViewIndex = getTargetIndexWithMethodReferenceName("getText") + val textViewRegister = + getInstruction(textViewIndex).registerC + + addInstructions( + textViewIndex, """ + invoke-static {v$textViewRegister}, $PLAYER_CLASS_DESCRIPTOR->setContainerClickListener(Landroid/view/View;)V + invoke-static {v$charSequenceRegister}, $PLAYER_CLASS_DESCRIPTOR->appendTimeStampInformation(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$charSequenceRegister + """ + ) + } + } + + // endregion + + // region patch for seekbar color + + PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { + hook(getWideLiteralInstructionIndex(InlineTimeBarColorizedBarPlayedColorDark) + 2) + hook(getWideLiteralInstructionIndex(InlineTimeBarPlayedNotHighlightedColor) + 2) + } + + ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { + hook(getWideLiteralInstructionIndex(ReelTimeBarPlayedColor) + 2) + } + + ControlsOverlayStyleFingerprint.resultOrThrow().let { + val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1) + walkerMethod.apply { + val colorRegister = getInstruction(0).registerA + + addInstructions( + 0, """ + invoke-static {v$colorRegister}, $PLAYER_CLASS_DESCRIPTOR->getSeekbarClickedColorValue(I)I + move-result v$colorRegister + """ + ) + } + } + + DrawableColorPatch.injectCall("$PLAYER_CLASS_DESCRIPTOR->getColor(I)I") + + contexts.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { + val layerList = it.file.getElementsByTagName("layer-list").item(0) as Element + val progressNode = layerList.getElementsByTagName("item").item(1) as Element + if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { + throw PatchException("Could not find progress bar") + } + val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element + val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element + val replacementNode = it.file.createElement( + "app.revanced.integrations.youtube.patches.utils.ProgressBarDrawable" + ) + scaleNode.replaceChild(replacementNode, shapeNode) + } + + // endregion + + // region patch for hide seekbar + + SeekbarFingerprint.resultOrThrow().mutableClass.let { mutableClass -> + SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekbar()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + } + } + + // endregion + + // region patch for hide time stamp + + PlayerSeekbarColorFingerprint.resultOrThrow().let { parentResult -> + TimeCounterFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideTimeStamp()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + } + } + + // endregion + + // region patch for restore old seekbar thumbnails + + ThumbnailPreviewConfigFingerprint.literalInstructionBooleanHook( + 45398577, + "$PLAYER_CLASS_DESCRIPTOR->restoreOldSeekbarThumbnails()Z" + ) + + // endregion + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: PLAYER", + "SETTINGS: SEEKBAR_COMPONENTS" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } + + private fun MutableMethod.hook(insertIndex: Int) { + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->overrideSeekbarColor(I)I + move-result v$insertRegister + """ + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ControlsOverlayStyleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ControlsOverlayStyleFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ControlsOverlayStyleFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ControlsOverlayStyleFingerprint.kt index 33a720e33..99bfcc6e5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ControlsOverlayStyleFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ControlsOverlayStyleFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.seekbar.color.fingerprints +package app.revanced.patches.youtube.player.seekbar.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/fingerprints/SeekbarTappingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/SeekbarTappingFingerprint.kt similarity index 93% rename from src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/fingerprints/SeekbarTappingFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/SeekbarTappingFingerprint.kt index c85af5700..3f1d73f16 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/fingerprints/SeekbarTappingFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/SeekbarTappingFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.seekbar.tapping.fingerprints +package app.revanced.patches.youtube.player.seekbar.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ShortsSeekbarColorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ShortsSeekbarColorFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ShortsSeekbarColorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ShortsSeekbarColorFingerprint.kt index d8c5e520f..7ce85b4aa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/fingerprints/ShortsSeekbarColorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ShortsSeekbarColorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.seekbar.color.fingerprints +package app.revanced.patches.youtube.player.seekbar.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelTimeBarPlayedColor diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/fingerprints/ThumbnailPreviewConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ThumbnailPreviewConfigFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/fingerprints/ThumbnailPreviewConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ThumbnailPreviewConfigFingerprint.kt index a2a3255ca..ce6bf6c4e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/fingerprints/ThumbnailPreviewConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/ThumbnailPreviewConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.seekbar.thumbnailpreview.fingerprints +package app.revanced.patches.youtube.player.seekbar.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/fingerprints/TimeCounterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/TimeCounterFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/fingerprints/TimeCounterFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/TimeCounterFingerprint.kt index dd9b6813d..c99002ca2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/fingerprints/TimeCounterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/fingerprints/TimeCounterFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.seekbar.timestamps.fingerprints +package app.revanced.patches.youtube.player.seekbar.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/SeekMessagePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/SeekMessagePatch.kt deleted file mode 100644 index 98326294e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/SeekMessagePatch.kt +++ /dev/null @@ -1,113 +0,0 @@ -package app.revanced.patches.youtube.player.seekmessage - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.player.seekmessage.fingerprints.SeekEduContainerFingerprint -import app.revanced.patches.youtube.player.seekmessage.fingerprints.SeekEduUndoOverlayFingerprint -import app.revanced.patches.youtube.utils.controlsoverlay.ControlsOverlayConfigPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SeekUndoEduOverlayStub -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -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.WideLiteralInstruction - -@Suppress("unused") -object SeekMessagePatch : BaseBytecodePatch( - name = "Hide seek message", - description = "Adds an option to hide the 'Slide left or right to seek' or 'Release to cancel' message container in the video player.", - dependencies = setOf( - ControlsOverlayConfigPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - SeekEduContainerFingerprint, - SeekEduUndoOverlayFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - SeekEduContainerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekMessage()Z - move-result v0 - if-eqz v0, :default - return-void - """, ExternalLabel("default", getInstruction(0)) - ) - } - } - - /** - * Added in YouTube v18.29.xx~ - */ - SeekEduUndoOverlayFingerprint.resultOrThrow().let { result -> - result.mutableMethod.apply { - val seekUndoCalls = implementation!!.instructions.withIndex() - .filter { instruction -> - (instruction.value as? WideLiteralInstruction)?.wideLiteral == SeekUndoEduOverlayStub - } - val insertIndex = seekUndoCalls.elementAt(seekUndoCalls.size - 1).index - val insertRegister = getInstruction(insertIndex).registerA - - val onClickListenerIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener") - val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1) - - addInstructionsWithLabels( - insertIndex, constComponent + """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekUndoMessage()Z - move-result v$insertRegister - if-nez v$insertRegister, :default - """, ExternalLabel("default", getInstruction(onClickListenerIndex + 1)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_SEEK_MESSAGE" - ) - ) - - SettingsPatch.updatePatchStatus("Hide seek message") - - } - - private fun MutableMethod.getConstComponent( - startIndex: Int, - endIndex: Int - ): String { - val constRegister = - getInstruction(endIndex).registerE - - for (index in endIndex downTo startIndex) { - val instruction = getInstruction(index) - if (instruction !is WideLiteralInstruction) - continue - - if ((instruction as OneRegisterInstruction).registerA != constRegister) - continue - - val constValue = (instruction as WideLiteralInstruction).wideLiteral.toInt() - - return "const/16 v$constRegister, $constValue" - } - return "" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduUndoOverlayFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduUndoOverlayFingerprint.kt deleted file mode 100644 index d17c71b92..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/seekmessage/fingerprints/SeekEduUndoOverlayFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.player.seekmessage.fingerprints - -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SeekUndoEduOverlayStub -import app.revanced.util.fingerprint.LiteralValueFingerprint - -internal object SeekEduUndoOverlayFingerprint : LiteralValueFingerprint( - returnType = "V", - literalSupplier = { SeekUndoEduOverlayStub } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/SpeedOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/SpeedOverlayPatch.kt deleted file mode 100644 index af0287638..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/speedoverlay/SpeedOverlayPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.youtube.player.speedoverlay - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.youtube.player.speedoverlay.fingerprints.RestoreSlideToSeekBehaviorFingerprint -import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverlayFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object SpeedOverlayPatch : BaseBytecodePatch( - name = "Disable speed overlay", - description = "Adds an option to disable 'Play at 2x speed' when pressing and holding in the video player.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - RestoreSlideToSeekBehaviorFingerprint, - SpeedOverlayFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - mapOf( - RestoreSlideToSeekBehaviorFingerprint to 45411329, - SpeedOverlayFingerprint to 45411330 - ).forEach { (fingerprint, literal) -> - fingerprint.literalInstructionBooleanHook( - literal, - "$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z" - ) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: DISABLE_SPEED_OVERLAY" - ) - ) - - SettingsPatch.updatePatchStatus("Disable speed overlay") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/SuggestedActionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/SuggestedActionsPatch.kt deleted file mode 100644 index fd561d149..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestactions/SuggestedActionsPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.youtube.player.suggestactions - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.player.suggestactions.fingerprints.SuggestedActionsFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object SuggestedActionsPatch : BaseBytecodePatch( - name = "Hide suggested actions", - description = "Adds an option to hide the suggested actions bar inside the player.", - dependencies = setOf( - LithoFilterPatch::class, - PlayerTypeHookPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(SuggestedActionsFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/SuggestedActionFilter;" - - override fun execute(context: BytecodeContext) { - SuggestedActionsFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $FILTER_CLASS_DESCRIPTOR->hideSuggestedActions(Landroid/view/View;)V" - - ) - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_SUGGESTED_ACTION" - ) - ) - - SettingsPatch.updatePatchStatus("Hide suggested actions") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/ChannelWatermarkPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/watermark/ChannelWatermarkPatch.kt deleted file mode 100644 index a41928005..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/watermark/ChannelWatermarkPatch.kt +++ /dev/null @@ -1,69 +0,0 @@ -package app.revanced.patches.youtube.player.watermark - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.player.watermark.fingerprints.WatermarkFingerprint -import app.revanced.patches.youtube.player.watermark.fingerprints.WatermarkParentFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object ChannelWatermarkPatch : BaseBytecodePatch( - name = "Hide channel watermark", - description = "Adds an option to hide creator's watermarks in the video player.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(WatermarkParentFingerprint) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/WaterMarkFilter;" - - override fun execute(context: BytecodeContext) { - - WatermarkParentFingerprint.resultOrThrow().let { parentResult -> - WatermarkFingerprint.also { - it.resolve( - context, - parentResult.classDef - ) - }.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val register = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex + 1, """ - invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->hideChannelWatermark(Z)Z - move-result v$register - """ - ) - } - } - } - - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: HIDE_CHANNEL_WATERMARK" - ) - ) - - SettingsPatch.updatePatchStatus("Hide channel watermark") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt deleted file mode 100644 index dfedee11a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.youtube.seekbar.append - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.youtube.utils.fingerprints.TotalTimeFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object AppendTimeStampInformationPatch : BaseBytecodePatch( - name = "Append time stamps information", - description = "Adds an option to add the current video quality or playback speed in brackets next to the current time.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TotalTimeFingerprint) -) { - override fun execute(context: BytecodeContext) { - TotalTimeFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1 - val charSequenceRegister = getInstruction(charSequenceIndex).registerA - val textViewIndex = getTargetIndexWithMethodReferenceName("getText") - val textViewRegister = - getInstruction(textViewIndex).registerC - - addInstructions( - textViewIndex, """ - invoke-static {v$textViewRegister}, $SEEKBAR_CLASS_DESCRIPTOR->setContainerClickListener(Landroid/view/View;)V - invoke-static {v$charSequenceRegister}, $SEEKBAR_CLASS_DESCRIPTOR->appendTimeStampInformation(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$charSequenceRegister - """ - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: APPEND_TIME_STAMP_INFORMATION" - ) - ) - - SettingsPatch.updatePatchStatus("Append time stamps information") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/SeekbarColorPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/SeekbarColorPatch.kt deleted file mode 100644 index 18d0d3692..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/color/SeekbarColorPatch.kt +++ /dev/null @@ -1,108 +0,0 @@ -package app.revanced.patches.youtube.seekbar.color - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.drawable.DrawableColorPatch -import app.revanced.patches.youtube.seekbar.color.fingerprints.ControlsOverlayStyleFingerprint -import app.revanced.patches.youtube.seekbar.color.fingerprints.ShortsSeekbarColorFingerprint -import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarColorizedBarPlayedColorDark -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarPlayedNotHighlightedColor -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelTimeBarPlayedColor -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts -import app.revanced.util.getWalkerMethod -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import org.w3c.dom.Element - -@Suppress("DEPRECATION", "SpellCheckingInspection", "unused") -object SeekbarColorPatch : BaseBytecodePatch( - name = "Custom seekbar color", - description = "Adds an option to customize seekbar colors in video players and video thumbnails.", - dependencies = setOf( - DrawableColorPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - ControlsOverlayStyleFingerprint, - PlayerSeekbarColorFingerprint, - ShortsSeekbarColorFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { - hook(getWideLiteralInstructionIndex(InlineTimeBarColorizedBarPlayedColorDark) + 2) - hook(getWideLiteralInstructionIndex(InlineTimeBarPlayedNotHighlightedColor) + 2) - } - - ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { - hook(getWideLiteralInstructionIndex(ReelTimeBarPlayedColor) + 2) - } - - ControlsOverlayStyleFingerprint.resultOrThrow().let { - val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1) - walkerMethod.apply { - val colorRegister = getInstruction(0).registerA - - addInstructions( - 0, """ - invoke-static {v$colorRegister}, $SEEKBAR_CLASS_DESCRIPTOR->getSeekbarClickedColorValue(I)I - move-result v$colorRegister - """ - ) - } - } - - DrawableColorPatch.injectCall("$SEEKBAR_CLASS_DESCRIPTOR->getColor(I)I") - - contexts.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { - val layerList = it.file.getElementsByTagName("layer-list").item(0) as Element - val progressNode = layerList.getElementsByTagName("item").item(1) as Element - if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { - throw PatchException("Could not find progress bar") - } - val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element - val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element - val replacementNode = it.file.createElement( - "app.revanced.integrations.youtube.patches.utils.ProgressBarDrawable" - ) - scaleNode.replaceChild(replacementNode, shapeNode) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: CUSTOM_SEEKBAR_COLOR" - ) - ) - - SettingsPatch.updatePatchStatus("Custom seekbar color") - - } - - private fun MutableMethod.hook(insertIndex: Int) { - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex + 1, """ - invoke-static {v$insertRegister}, $SEEKBAR_CLASS_DESCRIPTOR->overrideSeekbarColor(I)I - move-result v$insertRegister - """ - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/hide/SeekbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/hide/SeekbarPatch.kt deleted file mode 100644 index 2b97238a3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/hide/SeekbarPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.youtube.seekbar.hide - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.seekbar.color.SeekbarColorPatch -import app.revanced.patches.youtube.utils.fingerprints.SeekbarFingerprint -import app.revanced.patches.youtube.utils.fingerprints.SeekbarOnDrawFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object SeekbarPatch : BaseBytecodePatch( - name = "Hide seekbar", - description = "Adds an option to hide the seekbar in video player and video thumbnails.", - dependencies = setOf( - SeekbarColorPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(SeekbarFingerprint) -) { - override fun execute(context: BytecodeContext) { - - SeekbarFingerprint.resultOrThrow().mutableClass.let { mutableClass -> - SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $SEEKBAR_CLASS_DESCRIPTOR->hideSeekbar()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: HIDE_SEEKBAR" - ) - ) - - SettingsPatch.updatePatchStatus("Hide seekbar") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/SeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/SeekbarTappingPatch.kt deleted file mode 100644 index 84155a58b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/tapping/SeekbarTappingPatch.kt +++ /dev/null @@ -1,97 +0,0 @@ -package app.revanced.patches.youtube.seekbar.tapping - -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.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.seekbar.tapping.fingerprints.SeekbarTappingFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c -import com.android.tools.smali.dexlib2.dexbacked.reference.DexBackedMethodReference -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11n - -@Suppress("unused") -object SeekbarTappingPatch : BaseBytecodePatch( - name = "Enable seekbar tapping", - description = "Adds an option to enable tap-to-seek on the seekbar of the video player.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(SeekbarTappingFingerprint) -) { - override fun execute(context: BytecodeContext) { - SeekbarTappingFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val tapSeekIndex = it.scanResult.patternScanResult!!.startIndex + 1 - val tapSeekReference = getInstruction(tapSeekIndex).reference - val tapSeekClass = - context - .findClass(((tapSeekReference) as DexBackedMethodReference).definingClass)!! - .mutableClass - val tapSeekMethods = mutableMapOf() - - for (method in tapSeekClass.methods) { - if (method.implementation == null) - continue - - val instructions = method.implementation!!.instructions - // here we make sure we actually find the method because it has more than 7 instructions - if (instructions.count() != 10) - continue - - // we know that the 7th instruction has the opcode CONST_4 - val instruction = instructions.elementAt(6) - if (instruction.opcode != Opcode.CONST_4) - continue - - // the literal for this instruction has to be either 1 or 2 - val literal = (instruction as Instruction11n).narrowLiteral - - // method founds - if (literal == 1) - tapSeekMethods["P"] = method - else if (literal == 2) - tapSeekMethods["O"] = method - } - - val pMethod = tapSeekMethods["P"] - ?: throw PatchException("tapSeekMethod not found") - val oMethod = tapSeekMethods["O"] - ?: throw PatchException("tapSeekMethod not found") - - val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $SEEKBAR_CLASS_DESCRIPTOR->enableSeekbarTapping()Z - move-result v0 - if-eqz v0, :disabled - invoke-virtual { p0, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V - invoke-virtual { p0, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V - """, ExternalLabel("disabled", getInstruction(insertIndex)) - ) - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: ENABLE_SEEKBAR_TAPPING" - ) - ) - - SettingsPatch.updatePatchStatus("Enable seekbar tapping") - - } - - private lateinit var TappingLabel: String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/NewThumbnailPreviewPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/NewThumbnailPreviewPatch.kt deleted file mode 100644 index 4ae3f5f3e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/thumbnailpreview/NewThumbnailPreviewPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.youtube.seekbar.thumbnailpreview - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.youtube.seekbar.thumbnailpreview.fingerprints.ThumbnailPreviewConfigFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object NewThumbnailPreviewPatch : BaseBytecodePatch( - name = "Enable new thumbnail preview", - description = "Adds an option to enables the new seekbar thumbnails preview.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(ThumbnailPreviewConfigFingerprint) -) { - override fun execute(context: BytecodeContext) { - - ThumbnailPreviewConfigFingerprint.literalInstructionBooleanHook( - 45398577, - "$SEEKBAR_CLASS_DESCRIPTOR->enableNewThumbnailPreview()Z" - ) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: ENABLE_NEW_THUMBNAIL_PREVIEW" - ) - ) - - SettingsPatch.updatePatchStatus("Enable new thumbnail preview") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/TimeStampPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/TimeStampPatch.kt deleted file mode 100644 index cf2dc542f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/timestamps/TimeStampPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.youtube.seekbar.timestamps - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.seekbar.timestamps.fingerprints.TimeCounterFingerprint -import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object TimeStampPatch : BaseBytecodePatch( - name = "Hide time stamp", - description = "Adds an option to hide the timestamp in the bottom left of the video player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(PlayerSeekbarColorFingerprint) -) { - override fun execute(context: BytecodeContext) { - - PlayerSeekbarColorFingerprint.resultOrThrow().let { parentResult -> - TimeCounterFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $SEEKBAR_CLASS_DESCRIPTOR->hideTimeStamp()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: SEEKBAR_SETTINGS", - "SETTINGS: HIDE_TIME_STAMP" - ) - ) - - SettingsPatch.updatePatchStatus("Hide time stamp") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index c2af8056f..7ac81ddf1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -72,7 +72,7 @@ object ShortsComponentPatch : BaseBytecodePatch( /** * Comment button */ - ShortsButtonFingerprint.hideButton(RightComment, "hideShortsPlayerCommentsButton", false) + ShortsButtonFingerprint.hideButton(RightComment, "hideShortsCommentsButton", false) /** * Dislike button @@ -86,7 +86,7 @@ object ShortsComponentPatch : BaseBytecodePatch( addInstructionsWithLabels( constIndex + 1, """ - invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerDislikeButton()Z + invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsDislikeButton()Z move-result v$constRegister if-nez v$constRegister, :hide const v$constRegister, $ReelRightDislikeIcon @@ -98,7 +98,7 @@ object ShortsComponentPatch : BaseBytecodePatch( /** * Info panel */ - ShortsInfoPanelFingerprint.hideButtons(ReelPlayerInfoPanel, "hideShortsPlayerInfoPanel(Landroid/view/ViewGroup;)Landroid/view/ViewGroup;") + ShortsInfoPanelFingerprint.hideButtons(ReelPlayerInfoPanel, "hideShortsInfoPanel(Landroid/view/ViewGroup;)Landroid/view/ViewGroup;") /** * Like button @@ -111,7 +111,7 @@ object ShortsComponentPatch : BaseBytecodePatch( addInstructionsWithLabels( insertIndex + 1, """ - invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerLikeButton()Z + invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsLikeButton()Z move-result v$insertRegister if-nez v$insertRegister, :hide const v$insertRegister, $ReelRightLikeIcon @@ -123,11 +123,11 @@ object ShortsComponentPatch : BaseBytecodePatch( /** * Paid promotion */ - ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge, "hideShortsPlayerPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") - ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge2, "hideShortsPlayerPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") + ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") + ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge2, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;") /** - * Pivot button + * Sound button */ ShortsPivotLegacyFingerprint.result?.let { it.mutableMethod.apply { @@ -139,7 +139,7 @@ object ShortsComponentPatch : BaseBytecodePatch( addInstructionsWithLabels( insertIndex, """ - invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerPivotButton()Z + invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSoundButton()Z move-result v$targetRegister if-nez v$targetRegister, :hide """, ExternalLabel("hide", getInstruction(jumpIndex)) @@ -150,19 +150,19 @@ object ShortsComponentPatch : BaseBytecodePatch( val targetIndex = getWideLiteralInstructionIndex(ReelPivotButton) val insertIndex = getTargetIndexReversed(targetIndex, Opcode.INVOKE_STATIC) + 1 - hideButtons(insertIndex, "hideShortsPlayerPivotButton(Ljava/lang/Object;)Ljava/lang/Object;") + hideButtons(insertIndex, "hideShortsSoundButton(Ljava/lang/Object;)Ljava/lang/Object;") } } /** * Remix button */ - ShortsButtonFingerprint.hideButton(ReelDynRemix, "hideShortsPlayerRemixButton", true) + ShortsButtonFingerprint.hideButton(ReelDynRemix, "hideShortsRemixButton", true) /** * Share button */ - ShortsButtonFingerprint.hideButton(ReelDynShare, "hideShortsPlayerShareButton", true) + ShortsButtonFingerprint.hideButton(ReelDynShare, "hideShortsShareButton", true) LithoFilterPatch.addFilter(BUTTON_FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(SHELF_FILTER_CLASS_DESCRIPTOR) @@ -172,15 +172,12 @@ object ShortsComponentPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: SHORTS_SETTINGS", - "SETTINGS: HIDE_SHORTS_SHELF", - "SETTINGS: SHORTS_PLAYER_PARENT", + "PREFERENCE_SCREEN: SHORTS", "SETTINGS: HIDE_SHORTS_COMPONENTS" ) ) - SettingsPatch.updatePatchStatus("Hide shorts components") - + SettingsPatch.updatePatchStatus(this) } private fun MethodFingerprint.hideButton( diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt index 14a2ea010..f61902cf6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt @@ -32,7 +32,7 @@ object ShortsNavigationBarPatch : BytecodePatch( addInstruction( startIndex + 1, - "sput-object v$register, $SHORTS_CLASS_DESCRIPTOR->pivotBar:Ljava/lang/Object;" + "invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->setNavigationBar(Ljava/lang/Object;)V" ) } } @@ -43,7 +43,7 @@ object ShortsNavigationBarPatch : BytecodePatch( walkerMethod.addInstruction( 0, - "invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerNavigationBar()V" + "invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsNavigationBar()V" ) } @@ -54,7 +54,7 @@ object ShortsNavigationBarPatch : BytecodePatch( addInstructions( targetIndex + 1, """ - invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerNavigationBar(Landroid/view/View;)Landroid/view/View; + invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsNavigationBar(Landroid/view/View;)Landroid/view/View; move-result-object v$insertRegister """ ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt index 28b1ec8dd..e51a1bedf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsSubscriptionsButtonPatch.kt @@ -38,7 +38,7 @@ object ShortsSubscriptionsButtonPatch : BytecodePatch( addInstruction( insertIndex + 1, - "invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerSubscriptionsButton(Landroid/view/View;)V" + "invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(Landroid/view/View;)V" ) } } @@ -71,7 +71,7 @@ object ShortsSubscriptionsButtonPatch : BytecodePatch( addInstructions( insertIndex, """ - invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPlayerSubscriptionsButton(I)I + invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(I)I move-result v$register """ ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsToolBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsToolBarPatch.kt index 4a07c7327..adff05a31 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsToolBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsToolBarPatch.kt @@ -1,38 +1,30 @@ package app.revanced.patches.youtube.shorts.components import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.shorts.components.fingerprints.ToolBarBannerFingerprint +import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsToolBarFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch -import app.revanced.util.getWalkerMethod import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -@Patch(dependencies = [ToolBarHookPatch::class]) object ShortsToolBarPatch : BytecodePatch( - setOf(ToolBarBannerFingerprint) + setOf(ShortsToolBarFingerprint) ) { override fun execute(context: BytecodeContext) { - ToolBarBannerFingerprint.resultOrThrow().let { - val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex) + ShortsToolBarFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val insertRegister = getInstruction(insertIndex).registerA - walkerMethod.apply { - addInstructionsWithLabels( - 0, - """ - invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsToolBarBanner()Z - move-result v0 - if-nez v0, :hide - """, - ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1)) + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsToolBar(Z)Z + move-result v$insertRegister + """ ) } } - - ToolBarHookPatch.injectCall("$SHORTS_CLASS_DESCRIPTOR->hideShortsToolBarButton") } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsToolBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsToolBarFingerprint.kt new file mode 100644 index 000000000..f0de713d8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/fingerprints/ShortsToolBarFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.shorts.components.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 ShortsToolBarFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("Z", "L", "L"), + opcodes = listOf(Opcode.IPUT_BOOLEAN), + strings = listOf("Null topBarButtons") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/outlinebutton/ShortsOutlineButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/outlinebutton/ShortsOutlineButtonPatch.kt index 4ef4baf25..31252aa9b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/outlinebutton/ShortsOutlineButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/outlinebutton/ShortsOutlineButtonPatch.kt @@ -55,7 +55,7 @@ object ShortsOutlineButtonPatch : BaseResourcePatch( context.copyResources("youtube/shorts/outline", resourceGroup) } - SettingsPatch.updatePatchStatus("Shorts outline button") + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/repeat/ShortsRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/repeat/ShortsRepeatPatch.kt index df8ae200a..a7d94cc3f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/repeat/ShortsRepeatPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/repeat/ShortsRepeatPatch.kt @@ -10,9 +10,7 @@ import app.revanced.patches.youtube.shorts.repeat.fingerprints.ReelEnumStaticFin import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts import app.revanced.util.containsReferenceInstructionIndex -import app.revanced.util.copyXmlNode import app.revanced.util.findMutableMethodOf import app.revanced.util.getStringInstructionIndex import app.revanced.util.getTargetIndex @@ -55,23 +53,17 @@ object ShortsRepeatPatch : BaseBytecodePatch( } } - /** - * Copy arrays - */ - contexts.copyXmlNode("youtube/shorts/host", "values/arrays.xml", "resources") - /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: SHORTS_SETTINGS", - "SETTINGS: SHORTS_PLAYER_PARENT", + "PREFERENCE_SCREEN: SHORTS", "SETTINGS: CHANGE_SHORTS_REPEAT_STATE" ) ) - SettingsPatch.updatePatchStatus("Change shorts repeat state") + SettingsPatch.updatePatchStatus(this) } private fun MutableMethod.injectEnum( diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt index adafb3fd2..85e0e894b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/startupshortsreset/ResumingShortsOnStartupPatch.kt @@ -86,13 +86,11 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: SHORTS_SETTINGS", - "SETTINGS: SHORTS_PLAYER_PARENT", + "PREFERENCE_SCREEN: SHORTS", "SETTINGS: DISABLE_RESUMING_SHORTS_PLAYER" ) ) - SettingsPatch.updatePatchStatus("Disable resuming shorts on startup") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt index 2fddb8448..1fb4dc76f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt @@ -2,14 +2,16 @@ package app.revanced.patches.youtube.swipe.controls 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.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.swipe.controls.fingerprints.FullScreenEngagementOverlayFingerprint import app.revanced.patches.youtube.swipe.controls.fingerprints.HDRBrightnessFingerprint -import app.revanced.patches.youtube.swipe.controls.fingerprints.SwipeControlsHostActivityFingerprint +import app.revanced.patches.youtube.swipe.controls.fingerprints.WatchPanelGesturesFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.SWIPE_PATH import app.revanced.patches.youtube.utils.lockmodestate.LockModeStateHookPatch import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch @@ -21,12 +23,14 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts import app.revanced.util.ResourceGroup import app.revanced.util.copyResources +import app.revanced.util.getTargetIndex import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import app.revanced.util.transformMethods import app.revanced.util.traverseClassHierarchy import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.immutable.ImmutableMethod @@ -45,22 +49,28 @@ object SwipeControlsPatch : BaseBytecodePatch( fingerprints = setOf( FullScreenEngagementOverlayFingerprint, HDRBrightnessFingerprint, - SwipeControlsHostActivityFingerprint + WatchPanelGesturesFingerprint ) ) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = + private const val INTEGRATIONS_SWIPE_CONTROLS_HOST_ACTIVITY_CLASS_DESCRIPTOR = + "$INTEGRATIONS_PATH/swipecontrols/SwipeControlsHostActivity;" + + private const val INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR = "$SWIPE_PATH/SwipeControlsPatch;" override fun execute(context: BytecodeContext) { - val wrapperClass = SwipeControlsHostActivityFingerprint.resultOrThrow().mutableClass - val targetClass = mainActivityMutableClass + + // region patch for swipe controls patch + + val hostActivityClass = context.findClass(INTEGRATIONS_SWIPE_CONTROLS_HOST_ACTIVITY_CLASS_DESCRIPTOR)!!.mutableClass + val mainActivityClass = mainActivityMutableClass // inject the wrapper class from integrations into the class hierarchy of MainActivity (WatchWhileActivity) - wrapperClass.setSuperClass(targetClass.superclass) - targetClass.setSuperClass(wrapperClass.type) + hostActivityClass.setSuperClass(mainActivityClass.superclass) + mainActivityClass.setSuperClass(hostActivityClass.type) // ensure all classes and methods in the hierarchy are non-final, so we can override them in integrations - context.traverseClassHierarchy(targetClass) { + context.traverseClassHierarchy(mainActivityClass) { accessFlags = accessFlags and AccessFlags.FINAL.value.inv() transformMethods { ImmutableMethod( @@ -83,16 +93,20 @@ object SwipeControlsPatch : BaseBytecodePatch( addInstruction( viewIndex + 1, - "sput-object v$viewRegister, $INTEGRATIONS_CLASS_DESCRIPTOR->engagementOverlay:Landroid/view/View;" + "invoke-static {v$viewRegister}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->setFullscreenEngagementOverlayView(Landroid/view/View;)V" ) } } + // endregion + + // region patch for disable HDR auto brightness + HDRBrightnessFingerprint.result?.let { it.mutableMethod.apply { addInstructionsWithLabels( 0, """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->disableHDRAutoBrightness()Z + invoke-static {}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->disableHDRAutoBrightness()Z move-result v0 if-eqz v0, :default return-void @@ -105,22 +119,55 @@ object SwipeControlsPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( + "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS", "SETTINGS: DISABLE_HDR_BRIGHTNESS" ) ) } // no exceptions are raised for compatibility with all versions. + // endregion + + // region patch for enable watch panel gestures + + // Even if it fails to resolve the fingerprint, the [Swipe controls] patch should succeed. + // So instead of throwing an exception, it just prints WARNING. + WatchPanelGesturesFingerprint.result?.let { + it.mutableMethod.apply { + val literalIndex = getWideLiteralInstructionIndex(45372793) + val targetIndex = getTargetIndex(literalIndex, Opcode.MOVE_RESULT) + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableWatchPanelGestures()Z + move-result v$targetRegister + """ + ) + } + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS", + "SETTINGS: ENABLE_WATCH_PANEL_GESTEURES" + ) + ) + } ?: println("WARNING: Failed to resolve WatchPanelGesturesFingerprint") + + // endregion + /** * Add settings */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: SWIPE_SETTINGS", - "SETTINGS: SWIPE_CONTROLS" + "PREFERENCE_SCREEN: SWIPE_CONTROLS" ) ) - SettingsPatch.updatePatchStatus("Swipe controls") + SettingsPatch.updatePatchStatus(this) contexts.copyResources( "youtube/swipecontrols", diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeControlsHostActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeControlsHostActivityFingerprint.kt deleted file mode 100644 index 543596afa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeControlsHostActivityFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.swipe.controls.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH -import com.android.tools.smali.dexlib2.AccessFlags - -internal object SwipeControlsHostActivityFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = emptyList(), - customFingerprint = { methodDef, _ -> - methodDef.definingClass == "$INTEGRATIONS_PATH/swipecontrols/SwipeControlsHostActivity;" - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt new file mode 100644 index 000000000..51241db21 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.swipe.controls.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +internal object WatchPanelGesturesFingerprint : LiteralValueFingerprint( + returnType = "V", + literalSupplier = { 45372793 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/browseid/BrowseIdHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/browseid/BrowseIdHookPatch.kt index c40d1f769..7099543fa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/browseid/BrowseIdHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/browseid/BrowseIdHookPatch.kt @@ -10,7 +10,7 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.fingerprints.PathBuilderFingerprint import app.revanced.patches.youtube.utils.browseid.fingerprints.BrowseIdClassFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.SHARED_PATH import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.util.getStringInstructionIndex import app.revanced.util.getTargetIndex @@ -32,7 +32,7 @@ object BrowseIdHookPatch : BytecodePatch( ) ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$UTILS_PATH/BrowseIdPatch;" + "$SHARED_PATH/BrowseId;" override fun execute(context: BytecodeContext) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/AccountMenuParentFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/AccountMenuParentFingerprint.kt index c703ce4a1..1ad9860a1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/AccountMenuParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/AccountMenuParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints +package app.revanced.patches.youtube.utils.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CompactLink import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerButtonsVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PlayerButtonsVisibilityFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerButtonsVisibilityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PlayerButtonsVisibilityFingerprint.kt index b1902637f..e0b2b5382 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerButtonsVisibilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PlayerButtonsVisibilityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.playercontrols.fingerprints +package app.revanced.patches.youtube.utils.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/YouTubeControlsOverlayFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/YouTubeControlsOverlayFingerprint.kt index 801a7e2bd..727b29ced 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/YouTubeControlsOverlayFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/YouTubeControlsOverlayFingerprint.kt @@ -1,19 +1,34 @@ package app.revanced.patches.youtube.utils.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YoutubeControlsOverlay -import app.revanced.util.fingerprint.LiteralValueFingerprint +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patches.youtube.player.components.PlayerComponentsPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FadeDurationFast +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InsetOverlayViewLayout +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ScrimOverlay +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SeekUndoEduOverlayStub +import app.revanced.patches.youtube.utils.sponsorblock.SponsorBlockBytecodePatch +import app.revanced.util.containsWideLiteralInstructionIndex import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object YouTubeControlsOverlayFingerprint : LiteralValueFingerprint( +/** + * Several instructions are added to this method by different patches. + * Therefore, patches using this fingerprint should not use the [Opcode] pattern, + * and must access the index through the resourceId. + * + * The patches and resourceIds that use this fingerprint are as follows: + * - [PlayerComponentsPatch] uses [FadeDurationFast], [ScrimOverlay] and [SeekUndoEduOverlayStub]. + * - [SponsorBlockBytecodePatch] uses [InsetOverlayViewLayout]. + */ +internal object YouTubeControlsOverlayFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, parameters = emptyList(), - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ - ), - literalSupplier = { YoutubeControlsOverlay } + customFingerprint = { methodDef, _ -> + methodDef.containsWideLiteralInstructionIndex(FadeDurationFast) + && methodDef.containsWideLiteralInstructionIndex(InsetOverlayViewLayout) + && methodDef.containsWideLiteralInstructionIndex(ScrimOverlay) + && methodDef.containsWideLiteralInstructionIndex(SeekUndoEduOverlayStub) + } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt index f1c9903ff..591cc6d9c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt @@ -172,12 +172,10 @@ object SpoofPlayerParameterPatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "SETTINGS: EXPERIMENTAL_FLAGS", "SETTINGS: SPOOF_PLAYER_PARAMETER" ) ) - SettingsPatch.updatePatchStatus("Spoof player parameters") - + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt similarity index 70% rename from src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt index ed8b62278..467cc9fd0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt @@ -1,27 +1,24 @@ -package app.revanced.patches.youtube.player.suggestedvideoendscreen +package app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen 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.Patch import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.player.suggestedvideoendscreen.fingerprints.RemoveOnLayoutChangeListenerFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints.RemoveOnLayoutChangeListenerFingerprint import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndexReversed import app.revanced.util.getWalkerMethod -import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -@Suppress("unused") -object SuggestedVideoEndScreenPatch : BaseBytecodePatch( - name = "Fix suggested video end screen", - description = "Fixes an issue where the suggested video end screen is shown at the end of a video, regardless of whether autoplay setting is on or off.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(RemoveOnLayoutChangeListenerFingerprint) +@Patch( + description = "Fixes an issue where the suggested video end screen is always visible regardless of whether autoplay is set or not." +) +object SuggestedVideoEndScreenPatch : BytecodePatch( + setOf(RemoveOnLayoutChangeListenerFingerprint) ) { override fun execute(context: BytecodeContext) { @@ -64,18 +61,5 @@ object SuggestedVideoEndScreenPatch : BaseBytecodePatch( } } - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: PLAYER_EXPERIMENTAL_FLAGS", - "SETTINGS: HIDE_SUGGESTED_VIDEO_END_SCREEN" - ) - ) - - SettingsPatch.updatePatchStatus("Fix suggested video end screen") - } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt index 3eeb8c165..2c0f744e7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.player.suggestedvideoendscreen.fingerprints +package app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.ReferenceFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt index b27f6c831..c073e82fd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt @@ -41,7 +41,7 @@ object PlaybackSpeedFlyoutPanelHookPatch : BytecodePatch( INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR )!!.mutableClass videoUtilsMutableClass.methods.single { method -> - method.name == "showPlaybackSpeedFlyoutPanel" + method.name == "showPlaybackSpeedFlyoutMenu" }.apply { // add playback rate bottom sheet class videoUtilsMutableClass.staticFields.add( diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt index fd9e651d7..e17a35650 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt @@ -5,33 +5,27 @@ import app.revanced.patcher.patch.Patch @Suppress("MemberVisibilityCanBePrivate") object Constants { const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/youtube" + const val SHARED_PATH = "$INTEGRATIONS_PATH/shared" const val PATCHES_PATH = "$INTEGRATIONS_PATH/patches" const val ADS_PATH = "$PATCHES_PATH/ads" const val ALTERNATIVE_THUMBNAILS_PATH = "$PATCHES_PATH/alternativethumbnails" - const val BOTTOM_PLAYER_PATH = "$PATCHES_PATH/bottomplayer" const val COMPONENTS_PATH = "$PATCHES_PATH/components" - const val FLYOUT_PANEL_PATH = "$PATCHES_PATH/flyoutpanel" - const val FULLSCREEN_PATH = "$PATCHES_PATH/fullscreen" + const val FEED_PATH = "$PATCHES_PATH/feed" const val GENERAL_PATH = "$PATCHES_PATH/general" const val MISC_PATH = "$PATCHES_PATH/misc" - const val NAVIGATION_PATH = "$PATCHES_PATH/navigation" const val OVERLAY_BUTTONS_PATH = "$PATCHES_PATH/overlaybutton" const val PLAYER_PATH = "$PATCHES_PATH/player" - const val SEEKBAR_PATH = "$PATCHES_PATH/seekbar" const val SHORTS_PATH = "$PATCHES_PATH/shorts" const val SWIPE_PATH = "$PATCHES_PATH/swipe" const val UTILS_PATH = "$PATCHES_PATH/utils" const val VIDEO_PATH = "$PATCHES_PATH/video" + const val ADS_CLASS_DESCRIPTOR = "$ADS_PATH/AdsPatch;" const val ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR = "$ALTERNATIVE_THUMBNAILS_PATH/AlternativeThumbnailsPatch;" - const val BOTTOM_PLAYER_CLASS_DESCRIPTOR = "$BOTTOM_PLAYER_PATH/BottomPlayerPatch;" - const val FLYOUT_PANEL_CLASS_DESCRIPTOR = "$FLYOUT_PANEL_PATH/FlyoutPanelPatch;" - const val FULLSCREEN_CLASS_DESCRIPTOR = "$FULLSCREEN_PATH/FullscreenPatch;" + const val FEED_CLASS_DESCRIPTOR = "$FEED_PATH/FeedPatch;" const val GENERAL_CLASS_DESCRIPTOR = "$GENERAL_PATH/GeneralPatch;" - const val NAVIGATION_CLASS_DESCRIPTOR = "$NAVIGATION_PATH/NavigationPatch;" const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;" - const val SEEKBAR_CLASS_DESCRIPTOR = "$SEEKBAR_PATH/SeekBarPatch;" const val SHORTS_CLASS_DESCRIPTOR = "$SHORTS_PATH/ShortsPatch;" val COMPATIBLE_PACKAGE = setOf( @@ -63,90 +57,4 @@ object Constants { ) ) ) - - val LANGUAGE_LIST = arrayOf( - "values", - "values-af", - "values-am", - "values-ar", - "values-as", - "values-az", - "values-b+sr+Latn", - "values-be", - "values-bg", - "values-bn", - "values-bs", - "values-ca", - "values-cs", - "values-da", - "values-de", - "values-el", - "values-en-rGB", - "values-en-rIN", - "values-es", - "values-es-rUS", - "values-et", - "values-eu", - "values-fa", - "values-fi", - "values-fr", - "values-fr-rCA", - "values-gl", - "values-gu", - "values-hi", - "values-hr", - "values-hu", - "values-hy", - "values-in", - "values-is", - "values-it", - "values-iw", - "values-ja", - "values-ka", - "values-kk", - "values-km", - "values-kn", - "values-ko", - "values-ky", - "values-lo", - "values-lt", - "values-lv", - "values-mk", - "values-ml", - "values-mn", - "values-mr", - "values-ms", - "values-my", - "values-nb", - "values-ne", - "values-nl", - "values-or", - "values-pa", - "values-pl", - "values-pt", - "values-pt-rBR", - "values-pt-rPT", - "values-ro", - "values-ru", - "values-si", - "values-sk", - "values-sl", - "values-sq", - "values-sr", - "values-sv", - "values-sw", - "values-ta", - "values-te", - "values-th", - "values-tl", - "values-tr", - "values-uk", - "values-ur", - "values-uz", - "values-vi", - "values-zh-rCN", - "values-zh-rHK", - "values-zh-rTW", - "values-zu" - ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt index 1eeab6ae0..bba65c670 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt @@ -9,7 +9,7 @@ import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.SHARED_PATH import app.revanced.patches.youtube.utils.navigation.fingerprints.ActionBarSearchResultsFingerprint import app.revanced.patches.youtube.utils.navigation.fingerprints.NavigationEnumFingerprint import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButtonsCreateDrawableViewFingerprint @@ -45,10 +45,10 @@ object NavigationBarHookPatch : BytecodePatch( ), ) { internal const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$INTEGRATIONS_PATH/shared/NavigationBar;" + "$SHARED_PATH/NavigationBar;" private const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR = - "$INTEGRATIONS_PATH/shared/NavigationBar\$NavigationButton;" + "$SHARED_PATH/NavigationBar\$NavigationButton;" private lateinit var navigationTabCreatedCallback: MutableMethod diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt index 56ca7b6d6..512a67180 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsPatch.kt @@ -7,23 +7,32 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsResourcesFingerprint +import app.revanced.patches.youtube.utils.fingerprints.PlayerButtonsVisibilityFingerprint import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.ControlsLayoutInflateFingerprint -import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerButtonsVisibilityFingerprint -import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsPatchFingerprint +import app.revanced.patches.youtube.utils.playercontrols.fingerprints.MotionEventFingerprint +import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityEntityModelFingerprint import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName 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.instruction.TwoRegisterInstruction -@Patch(dependencies = [SharedResourceIdPatch::class]) +@Patch( + dependencies = [ + PlayerControlsVisibilityHookPatch::class, + SharedResourceIdPatch::class + ] +) object PlayerControlsPatch : BytecodePatch( setOf( PlayerButtonsResourcesFingerprint, - PlayerControlsPatchFingerprint, + PlayerControlsVisibilityEntityModelFingerprint, BottomControlsInflateFingerprint, ControlsLayoutInflateFingerprint, YouTubeControlsOverlayFingerprint @@ -33,20 +42,22 @@ object PlayerControlsPatch : BytecodePatch( "$UTILS_PATH/PlayerControlsPatch;" private lateinit var changeVisibilityMethod: MutableMethod + private lateinit var changeVisibilityNegatedImmediatelyMethod: MutableMethod private lateinit var initializeOverlayButtonsMethod: MutableMethod private lateinit var initializeSponsorBlockButtonsMethod: MutableMethod override fun execute(context: BytecodeContext) { - // new method + // region patch for hook visibility of play control buttons (e.g. pause, play button, etc) + PlayerButtonsVisibilityFingerprint.resolve( context, PlayerButtonsResourcesFingerprint.resultOrThrow().mutableClass ) PlayerButtonsVisibilityFingerprint.resultOrThrow().let { it.mutableMethod.apply { - val viewIndex = it.scanResult.patternScanResult!!.startIndex + 1 - val viewRegister = getInstruction(viewIndex).registerA + val viewIndex = getTargetIndex(Opcode.INVOKE_INTERFACE) + val viewRegister = getInstruction(viewIndex).registerD addInstruction( viewIndex + 1, @@ -55,7 +66,10 @@ object PlayerControlsPatch : BytecodePatch( } } - // legacy method + // endregion + + // region patch for hook visibility of play controls layout + PlayerControlsVisibilityFingerprint.resolve( context, YouTubeControlsOverlayFingerprint.resultOrThrow().mutableClass @@ -65,6 +79,27 @@ object PlayerControlsPatch : BytecodePatch( "invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->changeVisibility(Z)V" ) + // endregion + + // region patch for detecting motion events in play controls layout + + MotionEventFingerprint.resolve( + context, + YouTubeControlsOverlayFingerprint.resultOrThrow().mutableClass + ) + MotionEventFingerprint.resultOrThrow().mutableMethod.apply { + val insertIndex = getTargetIndexWithMethodReferenceName("setTranslationY") + 1 + + addInstruction( + insertIndex, + "invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate()V" + ) + } + + // endregion + + // region patch initialize of overlay button or SponsorBlock button + mapOf( BottomControlsInflateFingerprint to "initializeOverlayButtons", ControlsLayoutInflateFingerprint to "initializeSponsorBlockButtons" @@ -82,15 +117,36 @@ object PlayerControlsPatch : BytecodePatch( } } - PlayerControlsPatchFingerprint.resultOrThrow().let { - changeVisibilityMethod = it.mutableMethod + // endregion - initializeOverlayButtonsMethod = - it.mutableClass.methods.find { method -> method.name == "initializeOverlayButtons" }!! + // region set methods to inject into integration + + val playerControlsMutableClass = + context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass + + changeVisibilityMethod = + playerControlsMutableClass.methods.single { method -> + method.name == "changeVisibility" + && method.parameters == listOf("Z", "Z") + } + + changeVisibilityNegatedImmediatelyMethod = + playerControlsMutableClass.methods.single { method -> + method.name == "changeVisibilityNegatedImmediately" + } + + initializeOverlayButtonsMethod = + playerControlsMutableClass.methods.single { method -> + method.name == "initializeOverlayButtons" + } + + initializeSponsorBlockButtonsMethod = + playerControlsMutableClass.methods.single { method -> + method.name == "initializeSponsorBlockButtons" + } + + // endregion - initializeSponsorBlockButtonsMethod = - it.mutableClass.methods.find { method -> method.name == "initializeSponsorBlockButtons" }!! - } } private fun MutableMethod.initializeHook(classDescriptor: String) = @@ -105,13 +161,21 @@ object PlayerControlsPatch : BytecodePatch( "invoke-static {p0, p1}, $classDescriptor->changeVisibility(ZZ)V" ) + private fun changeVisibilityNegatedImmediateHook(classDescriptor: String) = + changeVisibilityNegatedImmediatelyMethod.addInstruction( + 0, + "invoke-static {}, $classDescriptor->changeVisibilityNegatedImmediate()V" + ) + internal fun hookOverlayButtons(classDescriptor: String) { initializeOverlayButtonsMethod.initializeHook(classDescriptor) changeVisibilityHook(classDescriptor) + changeVisibilityNegatedImmediateHook(classDescriptor) } internal fun hookSponsorBlockButtons(classDescriptor: String) { initializeSponsorBlockButtonsMethod.initializeHook(classDescriptor) changeVisibilityHook(classDescriptor) + changeVisibilityNegatedImmediateHook(classDescriptor) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsVisibilityHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsVisibilityHookPatch.kt new file mode 100644 index 000000000..f93109384 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/PlayerControlsVisibilityHookPatch.kt @@ -0,0 +1,49 @@ +package app.revanced.patches.youtube.utils.playercontrols + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityEntityModelFingerprint +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +@Patch(dependencies = [SharedResourceIdPatch::class]) +object PlayerControlsVisibilityHookPatch : BytecodePatch( + setOf(PlayerControlsVisibilityEntityModelFingerprint) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$UTILS_PATH/PlayerControlsVisibilityHookPatch;" + + override fun execute(context: BytecodeContext) { + + PlayerControlsVisibilityEntityModelFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val iGetReference = getInstruction(startIndex).reference + val staticReference = getInstruction(startIndex + 1).reference + + it.mutableClass.methods.find { method -> method.name == "" }?.apply { + val targetIndex = getTargetIndex(Opcode.IPUT_OBJECT) + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + iget v$targetRegister, v$targetRegister, $iGetReference + invoke-static {v$targetRegister}, $staticReference + move-result-object v$targetRegister + invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerControlsVisibility(Ljava/lang/Enum;)V + """ + ) + } ?: throw PatchException("Constructor method not found") + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/MotionEventFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/MotionEventFingerprint.kt new file mode 100644 index 000000000..45d9d329d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/MotionEventFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.youtube.utils.playercontrols.fingerprints + +import app.revanced.util.fingerprint.MethodReferenceNameFingerprint + +internal object MotionEventFingerprint : MethodReferenceNameFingerprint( + returnType = "V", + parameters = listOf("Landroid/view/MotionEvent;"), + reference = { "setTranslationY" } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsPatchFingerprint.kt deleted file mode 100644 index 7d4b1231d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsPatchFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.youtube.utils.playercontrols.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import com.android.tools.smali.dexlib2.AccessFlags - -internal object PlayerControlsPatchFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, - parameters = listOf("Z", "Z"), - customFingerprint = { methodDef, _ -> - methodDef.definingClass == "$UTILS_PATH/PlayerControlsPatch;" - && methodDef.name == "changeVisibility" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsVisibilityEntityModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsVisibilityEntityModelFingerprint.kt new file mode 100644 index 000000000..316e8b55e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playercontrols/fingerprints/PlayerControlsVisibilityEntityModelFingerprint.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.youtube.utils.playercontrols.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object PlayerControlsVisibilityEntityModelFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC.value, + parameters = emptyList(), + opcodes = listOf( + Opcode.IGET, + Opcode.INVOKE_STATIC + ), + customFingerprint = { methodDef, _ -> methodDef.name == "getPlayerControlsVisibility" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/QuickActionsHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/QuickActionsHookPatch.kt deleted file mode 100644 index c7279c677..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/quickactions/QuickActionsHookPatch.kt +++ /dev/null @@ -1,52 +0,0 @@ -package app.revanced.patches.youtube.utils.quickactions - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.utils.integrations.Constants.FULLSCREEN_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.quickactions.fingerprints.QuickActionsElementFingerprint -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QuickActionsElementContainer -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction - -@Patch(dependencies = [SharedResourceIdPatch::class]) -object QuickActionsHookPatch : BytecodePatch( - setOf(QuickActionsElementFingerprint) -) { - private lateinit var insertMethod: MutableMethod - private var insertIndex: Int = 0 - private var insertRegister: Int = 0 - override fun execute(context: BytecodeContext) { - - QuickActionsElementFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - insertMethod = this - val containerCalls = implementation!!.instructions.withIndex() - .filter { instruction -> - (instruction.value as? WideLiteralInstruction)?.wideLiteral == QuickActionsElementContainer - } - val constIndex = containerCalls.elementAt(containerCalls.size - 1).index - insertRegister = - getInstruction(constIndex + 2).registerA - - addInstruction( - constIndex + 3, - "invoke-static {v$insertRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->hideQuickActions(Landroid/view/View;)V" - ) - insertIndex = constIndex + 5 - } - } - } - - internal fun injectQuickActionMargin() { - insertMethod.addInstruction( - insertIndex, - "invoke-static {v$insertRegister}, $FULLSCREEN_CLASS_DESCRIPTOR->setQuickActionMargin(Landroid/widget/FrameLayout;)V" - ) - } -} 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 4f3532e26..b3b3b79c2 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 @@ -77,7 +77,6 @@ object SharedResourceIdPatch : ResourcePatch() { var ScrimOverlay = -1L var Scrubbing = -1L var SeekUndoEduOverlayStub = -1L - var SettingsBooleanTimeRangeDialog = -1L var SlidingDialogAnimation = -1L var SubtitleMenuSettingsFooterInfo = -1L var SuggestedAction = -1L @@ -85,9 +84,7 @@ object SharedResourceIdPatch : ResourcePatch() { var ToolTipContentView = -1L var TotalTime = -1L var VideoQualityBottomSheet = -1L - var VideoZoomIndicatorLayout = -1L - var YoutubeControlsOverlay = -1L - var YoutubeControlsOverlaySubtitleButton = -1L + var YouTubeControlsOverlaySubtitleButton = -1L override fun execute(context: ResourceContext) { @@ -154,7 +151,6 @@ object SharedResourceIdPatch : ResourcePatch() { ScrimOverlay = getId(ID, "scrim_overlay") Scrubbing = getId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") SeekUndoEduOverlayStub = getId(ID, "seek_undo_edu_overlay_stub") - SettingsBooleanTimeRangeDialog = getId(LAYOUT, "setting_boolean_time_range_dialog") SlidingDialogAnimation = getId(STYLE, "SlidingDialogAnimation") SubtitleMenuSettingsFooterInfo = getId(STRING, "subtitle_menu_settings_footer_info") SuggestedAction = getId(LAYOUT, "suggested_action") @@ -162,9 +158,7 @@ object SharedResourceIdPatch : ResourcePatch() { ToolTipContentView = getId(LAYOUT, "tooltip_content_view") TotalTime = getId(STRING, "total_time") VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title") - VideoZoomIndicatorLayout = getId(ID, "video_zoom_indicator_layout") - YoutubeControlsOverlay = getId(ID, "youtube_controls_overlay") - YoutubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button") + YouTubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button") } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt index 29dd821ba..84bf2c490 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt @@ -110,11 +110,11 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: RETURN_YOUTUBE_DISLIKE_SETTINGS" + "PREFERENCE_SCREEN: RETURN_YOUTUBE_DISLIKE" ) ) - SettingsPatch.updatePatchStatus("Return YouTube Dislike") + SettingsPatch.updatePatchStatus(this) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt index 8742538d3..17ba9ae60 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt @@ -13,6 +13,7 @@ import app.revanced.util.ResourceGroup import app.revanced.util.classLoader import app.revanced.util.copyResources import app.revanced.util.copyXmlNode +import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseResourcePatch import org.w3c.dom.Element import java.io.Closeable @@ -41,6 +42,7 @@ object SettingsPatch : BaseResourcePatch( internal var upward1831 = false internal var upward1834 = false internal var upward1839 = false + internal var upward1842 = false internal var upward1849 = false internal var upward1902 = false internal var upward1909 = false @@ -74,6 +76,7 @@ object SettingsPatch : BaseResourcePatch( upward1831 = 233200000 <= playServicesVersion upward1834 = 233500000 <= playServicesVersion upward1839 = 234000000 <= playServicesVersion + upward1842 = 234302000 <= playServicesVersion upward1849 = 235000000 <= playServicesVersion upward1902 = 240204000 < playServicesVersion upward1909 = 241002000 <= playServicesVersion @@ -89,28 +92,24 @@ object SettingsPatch : BaseResourcePatch( .awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) /** - * copy strings and preference + * copy arrays, strings and preference */ - context.copyXmlNode("youtube/settings/host", "values/strings.xml", "resources") - context.copyResources( - "youtube/settings", - ResourceGroup("xml", "revanced_prefs.xml") - ) - - /** - * create directory for the untranslated language resources - */ - context["res/values-v21"].mkdirs() + arrayOf( + "arrays.xml", + "strings.xml" + ).forEach { xmlFile -> + context.copyXmlNode("youtube/settings/host", "values/$xmlFile", "resources") + } arrayOf( ResourceGroup( "layout", "revanced_settings_preferences_category.xml", - "revanced_settings_with_toolbar.xml" + "revanced_settings_with_toolbar.xml", ), ResourceGroup( - "values-v21", - "strings.xml" + "xml", + "revanced_prefs.xml", ) ).forEach { resourceGroup -> context.copyResources("youtube/settings", resourceGroup) @@ -151,6 +150,14 @@ object SettingsPatch : BaseResourcePatch( contexts.addPreference(settingArray) } + internal fun updatePatchStatus(patch: BaseResourcePatch) { + updatePatchStatus(patch.name!!) + } + + internal fun updatePatchStatus(patch: BaseBytecodePatch) { + updatePatchStatus(patch.name!!) + } + internal fun updatePatchStatus(patchTitle: String) { contexts.updatePatchStatus(patchTitle) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockBytecodePatch.kt index ac0b5b576..8c8639501 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockBytecodePatch.kt @@ -56,6 +56,9 @@ object SponsorBlockBytecodePatch : BytecodePatch( private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = "$INTEGRATIONS_SPONSOR_BLOCK_PATH/SegmentPlaybackController;" + private const val INTEGRATIONS_SPONSOR_BLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR = + "$INTEGRATIONS_SPONSOR_BLOCK_UI_PATH/SponsorBlockViewController;" + override fun execute(context: BytecodeContext) { VideoInformationPatch.apply { @@ -134,7 +137,7 @@ object SponsorBlockBytecodePatch : BytecodePatch( addInstruction( checkCastIndex + 1, - "invoke-static {v$targetRegister}, $INTEGRATIONS_SPONSOR_BLOCK_UI_PATH/SponsorBlockViewController;->initialize(Landroid/view/ViewGroup;)V" + "invoke-static {v$targetRegister}, $INTEGRATIONS_SPONSOR_BLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V" ) } } @@ -161,6 +164,14 @@ object SponsorBlockBytecodePatch : BytecodePatch( } } + // 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. + VideoInformationPatch.videoEndMethod.addInstruction( + 0, + "invoke-static {}, $INTEGRATIONS_SPONSOR_BLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" + ) + // Set current video id VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockPatch.kt index e59ab371e..6007d888d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/sponsorblock/SponsorBlockPatch.kt @@ -141,11 +141,11 @@ object SponsorBlockPatch : BaseResourcePatch( */ SettingsPatch.addPreference( arrayOf( - "PREFERENCE: SPONSOR_BLOCK_SETTINGS" + "PREFERENCE_SCREEN: SPONSOR_BLOCK" ) ) - SettingsPatch.updatePatchStatus("SponsorBlock") + SettingsPatch.updatePatchStatus(this) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/ViewGroupMarginLayoutParamsHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/ViewGroupMarginLayoutParamsHookPatch.kt new file mode 100644 index 000000000..d51593bfd --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/ViewGroupMarginLayoutParamsHookPatch.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.youtube.utils.viewgroup + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.youtube.utils.fingerprints.AccountMenuParentFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.viewgroup.fingerprints.SetViewGroupMarginFingerprint +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction + +@Patch( + description = "Hook YouTube to use ViewGroup.MarginLayoutParams in the integration.", + dependencies = [SharedResourceIdPatch::class], +) +object ViewGroupMarginLayoutParamsHookPatch : BytecodePatch( + setOf(AccountMenuParentFingerprint) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$UTILS_PATH/ViewGroupMarginLayoutParamsPatch;" + + override fun execute(context: BytecodeContext) { + + val method = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method -> + method.name == "hideViewGroupByMarginLayoutParams" + } ?: throw PatchException("Could not find hideViewGroupByMarginLayoutParams method") + + SetViewGroupMarginFingerprint.resolve( + context, + AccountMenuParentFingerprint.resultOrThrow().classDef + ) + SetViewGroupMarginFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val setViewGroupMarginIndex = it.scanResult.patternScanResult!!.startIndex + val setViewGroupMarginReference = + getInstruction(setViewGroupMarginIndex).reference + + method.addInstructions( + 0, """ + const/4 v0, 0x0 + invoke-static {p0, v0, v0}, $setViewGroupMarginReference + """ + ) + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/SetViewGroupMarginFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/fingerprints/SetViewGroupMarginFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/SetViewGroupMarginFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/fingerprints/SetViewGroupMarginFingerprint.kt index c32c88933..1253cf6f3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/accountmenu/fingerprints/SetViewGroupMarginFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/viewgroup/fingerprints/SetViewGroupMarginFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.general.accountmenu.fingerprints +package app.revanced.patches.youtube.utils.viewgroup.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedPatch.kt deleted file mode 100644 index e9d5c276b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedPatch.kt +++ /dev/null @@ -1,49 +0,0 @@ -package app.revanced.patches.youtube.video.customspeed - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object CustomPlaybackSpeedPatch : BaseResourcePatch( - name = "Custom playback speed", - description = "Adds an option to customize available playback speeds.", - dependencies = setOf( - CustomPlaybackSpeedBytecodePatch::class, - BottomSheetRecyclerViewPatch::class, - LithoFilterPatch::class, - PlaybackSpeedFlyoutPanelHookPatch::class, - SettingsPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/PlaybackSpeedMenuFilter;" - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$VIDEO_PATH/CustomPlaybackSpeedPatch;" - - override fun execute(context: ResourceContext) { - BottomSheetRecyclerViewPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: VIDEO_SETTINGS", - "SETTINGS: CUSTOM_PLAYBACK_SPEED" - ) - ) - - SettingsPatch.updatePatchStatus("Custom playback speed") - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/hdr/HDRVideoPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/hdr/HDRVideoPatch.kt deleted file mode 100644 index 9780110ba..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/hdr/HDRVideoPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.youtube.video.hdr - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.video.hdr.fingerprints.HDRCapabilityFingerprint -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object HDRVideoPatch : BaseBytecodePatch( - name = "Disable HDR video", - description = "Adds options to disable HDR video.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(HDRCapabilityFingerprint) -) { - override fun execute(context: BytecodeContext) { - - HDRCapabilityFingerprint.resultOrThrow().mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $VIDEO_PATH/HDRVideoPatch;->disableHDRVideo()Z - move-result v0 - if-nez v0, :default - return v0 - """, ExternalLabel("default", getInstruction(0)) - ) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: VIDEO_SETTINGS", - "SETTINGS: DISABLE_HDR_VIDEO" - ) - ) - - SettingsPatch.updatePatchStatus("Disable HDR video") - - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index 166f23ec1..cb3150163 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -9,14 +9,13 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.toInstructions import app.revanced.patches.youtube.utils.fingerprints.OrganicPlaybackContextModelFingerprint import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.SHARED_PATH import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.video.information.fingerprints.OnPlaybackSpeedItemClickFingerprint @@ -27,6 +26,7 @@ import app.revanced.patches.youtube.video.information.fingerprints.VideoQualityL import app.revanced.patches.youtube.video.information.fingerprints.VideoQualityTextFingerprint import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch +import app.revanced.util.addFieldAndInstructions import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndexReversed import app.revanced.util.getWalkerMethod @@ -37,7 +37,6 @@ 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.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter @@ -65,7 +64,7 @@ object VideoInformationPatch : BytecodePatch( ) ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$VIDEO_PATH/VideoInformation;" + "$SHARED_PATH/VideoInformation;" private lateinit var playerConstructorMethod: MutableMethod private var playerConstructorInsertIndex = 4 @@ -78,8 +77,11 @@ object VideoInformationPatch : BytecodePatch( // Used by other patches. internal lateinit var speedSelectionInsertMethod: MutableMethod + internal lateinit var videoEndMethod: MutableMethod override fun execute(context: BytecodeContext) { + val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass + VideoEndFingerprint.resultOrThrow().let { playerConstructorMethod = it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } @@ -112,7 +114,27 @@ object VideoInformationPatch : BytecodePatch( ).toMutable() ) - val videoEndMethod = getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1) + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0, p1}, $definingClass->seekTo(J)Z + move-result v0 + return v0 + :ignore + const/4 v0, 0x0 + return v0 + """ + + videoInformationMutableClass.addFieldAndInstructions( + context, + "overrideVideoTime", + "videoInformationClass", + definingClass, + smaliInstructions, + true + ) + + videoEndMethod = getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1) videoEndMethod.apply { addInstructionsWithLabels( @@ -175,8 +197,6 @@ object VideoInformationPatch : BytecodePatch( PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameterBeforeVideoId( "$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;") - val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass - /** * Hook current playback speed */ @@ -253,33 +273,22 @@ object VideoInformationPatch : BytecodePatch( "return-object v$register" ) - videoInformationMutableClass.methods.single { method -> - method.name == "overridePlaybackSpeed" - }.apply { - // add playback speed class - videoInformationMutableClass.staticFields.add( - ImmutableField( - definingClass, - "playbackSpeedClass", - playbackSpeedClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - ) + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V + :ignore + return-void + """ - // call override playback speed method - addInstructionsWithLabels( - 0, """ - sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass - if-eqz v0, :ignore - invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V - :ignore - return-void - """ - ) - } + videoInformationMutableClass.addFieldAndInstructions( + context, + "overridePlaybackSpeed", + "playbackSpeedClass", + playbackSpeedClass, + smaliInstructions, + false + ) } } @@ -287,8 +296,6 @@ object VideoInformationPatch : BytecodePatch( * Hook current video quality */ VideoQualityListFingerprint.resultOrThrow().let { - val constructorMethod = - it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } val overrideMethod = it.mutableClass.methods.find { method -> method.parameterTypes.first() == "I" } @@ -296,14 +303,6 @@ object VideoInformationPatch : BytecodePatch( val videoQualityMethodName = overrideMethod?.name ?: throw PatchException("Failed to find hook method") - // set video quality class - constructorMethod.apply { - addInstruction( - 2, - "sput-object p0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass" - ) - } - // set video quality array it.mutableMethod.apply { val listIndex = it.scanResult.patternScanResult!!.startIndex @@ -315,33 +314,22 @@ object VideoInformationPatch : BytecodePatch( ) } - videoInformationMutableClass.methods.single { method -> - method.name == "overrideVideoQuality" - }.apply { - // add video quality class - videoInformationMutableClass.staticFields.add( - ImmutableField( - definingClass, - "videoQualityClass", - videoQualityClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - ) + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0}, $videoQualityClass->$videoQualityMethodName(I)V + :ignore + return-void + """ - // call override video quality method - addInstructionsWithLabels( - 0, """ - sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass - if-eqz v0, :ignore - invoke-virtual {v0, p0}, $videoQualityClass->$videoQualityMethodName(I)V - :ignore - return-void - """ - ) - } + videoInformationMutableClass.addFieldAndInstructions( + context, + "overrideVideoQuality", + "videoQualityClass", + videoQualityClass, + smaliInstructions, + true + ) } // set current video quality @@ -374,10 +362,9 @@ object VideoInformationPatch : BytecodePatch( * @param targetMethodName The name of the static method to invoke when the player controller is created. */ internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = - playerConstructorMethod.insert( + playerConstructorMethod.addInstruction( playerConstructorInsertIndex++, - "v0", - "$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V" + "invoke-static {}, $targetMethodClass->$targetMethodName()V" ) /** diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/CustomPlaybackSpeedPatch.kt similarity index 62% rename from src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/CustomPlaybackSpeedPatch.kt index 99622b9e4..c99deb1ab 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/CustomPlaybackSpeedPatch.kt @@ -1,9 +1,9 @@ -package app.revanced.patches.youtube.video.customspeed +package app.revanced.patches.youtube.video.playback import app.revanced.patches.shared.customspeed.BaseCustomPlaybackSpeedPatch import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH -object CustomPlaybackSpeedBytecodePatch : BaseCustomPlaybackSpeedPatch( +object CustomPlaybackSpeedPatch : BaseCustomPlaybackSpeedPatch( "$VIDEO_PATH/CustomPlaybackSpeedPatch;", 8.0f ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt new file mode 100644 index 000000000..0d07e4c13 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt @@ -0,0 +1,270 @@ +package app.revanced.patches.youtube.video.playback + +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.PatchException +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.youtube.utils.fingerprints.QualityMenuViewInflateFingerprint +import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint +import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch +import app.revanced.patches.youtube.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch +import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH +import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.video.information.VideoInformationPatch +import app.revanced.patches.youtube.video.information.VideoInformationPatch.speedSelectionInsertMethod +import app.revanced.patches.youtube.video.playback.fingerprints.DeviceDimensionsModelToStringFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.HDRCapabilityFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.PlaybackSpeedChangedFromRecyclerViewFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.PlaybackSpeedInitializeFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.QualityChangedFromRecyclerViewFingerprint +import app.revanced.patches.youtube.video.playback.fingerprints.QualitySetterFingerprint +import app.revanced.patches.youtube.video.videoid.VideoIdPatch +import app.revanced.util.getReference +import app.revanced.util.getTargetIndex +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import app.revanced.util.updatePatchStatus +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +@Suppress("unused") +object VideoPlaybackPatch : BaseBytecodePatch( + name = "Video playback", + description = "Adds options to customize settings related to video playback," + + "such as default video quality and playback speed, etc.", + dependencies = setOf( + BottomSheetRecyclerViewPatch::class, + CustomPlaybackSpeedPatch::class, + LithoFilterPatch::class, + PlaybackSpeedFlyoutPanelHookPatch::class, + PlayerTypeHookPatch::class, + SettingsPatch::class, + ShortsPlaybackPatch::class, + VideoIdPatch::class, + VideoInformationPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + DeviceDimensionsModelToStringFingerprint, + HDRCapabilityFingerprint, + PlaybackSpeedChangedFromRecyclerViewFingerprint, + PlaybackSpeedInitializeFingerprint, + QualityChangedFromRecyclerViewFingerprint, + QualityMenuViewInflateFingerprint, + QualitySetterFingerprint, + VideoEndFingerprint + ) +) { + private const val PLAYBACK_SPEED_MENU_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/PlaybackSpeedMenuFilter;" + private const val VIDEO_QUALITY_MENU_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/VideoQualityMenuFilter;" + private const val INTEGRATIONS_CUSTOM_PLAYBACK_SPEED_CLASS_DESCRIPTOR = + "$VIDEO_PATH/CustomPlaybackSpeedPatch;" + private const val INTEGRATIONS_HDR_VIDEO_CLASS_DESCRIPTOR = + "$VIDEO_PATH/HDRVideoPatch;" + private const val INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR = + "$VIDEO_PATH/PlaybackSpeedPatch;" + private const val INTEGRATIONS_RELOAD_VIDEO_CLASS_DESCRIPTOR = + "$VIDEO_PATH/ReloadVideoPatch;" + private const val INTEGRATIONS_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR = + "$VIDEO_PATH/RestoreOldVideoQualityMenuPatch;" + private const val INTEGRATIONS_SPOOF_DEVICE_DIMENSIONS_CLASS_DESCRIPTOR = + "$VIDEO_PATH/SpoofDeviceDimensionsPatch;" + private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = + "$VIDEO_PATH/VideoQualityPatch;" + + override fun execute(context: BytecodeContext) { + + // region patch for custom playback speed + + BottomSheetRecyclerViewPatch.injectCall("$INTEGRATIONS_CUSTOM_PLAYBACK_SPEED_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") + LithoFilterPatch.addFilter(PLAYBACK_SPEED_MENU_FILTER_CLASS_DESCRIPTOR) + + // endregion + + // region patch for disable HDR video + + HDRCapabilityFingerprint.resultOrThrow().mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $INTEGRATIONS_HDR_VIDEO_CLASS_DESCRIPTOR->disableHDRVideo()Z + move-result v0 + if-nez v0, :default + return v0 + """, ExternalLabel("default", getInstruction(0)) + ) + } + + // endregion + + // region patch for default playback speed + + PlaybackSpeedChangedFromRecyclerViewFingerprint.resolve( + context, + QualityChangedFromRecyclerViewFingerprint.resultOrThrow().classDef + ) + + val newMethod = PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod + + arrayOf( + newMethod, + speedSelectionInsertMethod + ).forEach { + it.apply { + val speedSelectionValueInstructionIndex = getTargetIndex(Opcode.IGET) + val speedSelectionValueRegister = + getInstruction(speedSelectionValueInstructionIndex).registerA + + addInstruction( + speedSelectionValueInstructionIndex + 1, + "invoke-static {v$speedSelectionValueRegister}, " + + "$INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->userSelectedPlaybackSpeed(F)V" + ) + } + } + + PlaybackSpeedInitializeFingerprint.resolve( + context, + VideoEndFingerprint.resultOrThrow().classDef + ) + PlaybackSpeedInitializeFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeedInShorts(F)F + move-result v$insertRegister + """ + ) + } + } + + VideoInformationPatch.cpnHook("$INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Z)V") + + context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "RememberPlaybackSpeed") + + // endregion + + // region patch for default video quality + + QualityChangedFromRecyclerViewFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val index = it.scanResult.patternScanResult!!.startIndex + + addInstruction( + index + 1, + "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" + ) + + } + } + + QualitySetterFingerprint.resultOrThrow().let { + val onItemClickMethod = + it.mutableClass.methods.find { method -> method.name == "onItemClick" } + + onItemClickMethod?.apply { + addInstruction( + 0, + "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" + ) + } ?: throw PatchException("Failed to find onItemClick method") + } + + VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") + VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_RELOAD_VIDEO_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") + + // endregion + + // region patch for restore old video quality menu + + val videoQualityClass = QualitySetterFingerprint.resultOrThrow().mutableMethod.definingClass + + QualityMenuViewInflateFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getTargetIndex(Opcode.CHECK_CAST) + val insertRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex + 1, + "invoke-static { v$insertRegister }, " + + "$INTEGRATIONS_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR->showOldVideoQualityMenu(Landroid/widget/ListView;)V" + ) + } + val onItemClickMethod = + it.mutableClass.methods.find { method -> method.name == "onItemClick" } + + onItemClickMethod?.apply { + val insertIndex = getTargetIndex(Opcode.IGET_OBJECT) + val insertRegister = getInstruction(insertIndex).registerA + + val jumpIndex = indexOfFirstInstruction { + opcode == Opcode.IGET_OBJECT + && this.getReference()?.type == videoQualityClass + } + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $INTEGRATIONS_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR->showOldVideoQualityMenu()Z + move-result v$insertRegister + if-nez v$insertRegister, :show + """, ExternalLabel("show", getInstruction(jumpIndex)) + ) + } ?: throw PatchException("Failed to find onItemClick method") + } + + BottomSheetRecyclerViewPatch.injectCall("$INTEGRATIONS_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") + LithoFilterPatch.addFilter(VIDEO_QUALITY_MENU_FILTER_CLASS_DESCRIPTOR) + + // endregion + + // region patch for spoof device dimensions + + DeviceDimensionsModelToStringFingerprint.resultOrThrow().let { result -> + result.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } + .addInstructions( + 1, // Add after super call. + mapOf( + 1 to "MinHeightOrWidth", // p1 = min height + 2 to "MaxHeightOrWidth", // p2 = max height + 3 to "MinHeightOrWidth", // p3 = min width + 4 to "MaxHeightOrWidth" // p4 = max width + ).map { (parameter, method) -> + """ + invoke-static { p$parameter }, $INTEGRATIONS_SPOOF_DEVICE_DIMENSIONS_CLASS_DESCRIPTOR->get$method(I)I + move-result p$parameter + """ + }.joinToString("\n") { it } + ) + } + + // endregion + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE_SCREEN: VIDEO" + ) + ) + + SettingsPatch.updatePatchStatus(this) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/fingerprints/DeviceDimensionsModelToStringFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/DeviceDimensionsModelToStringFingerprint.kt similarity index 73% rename from src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/fingerprints/DeviceDimensionsModelToStringFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/DeviceDimensionsModelToStringFingerprint.kt index f9980d03c..42270bb2d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofdimensions/fingerprints/DeviceDimensionsModelToStringFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/DeviceDimensionsModelToStringFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.spoofdimensions.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/hdr/fingerprints/HDRCapabilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/HDRCapabilityFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/video/hdr/fingerprints/HDRCapabilityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/HDRCapabilityFingerprint.kt index 6e9b1b758..8b9896e2c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/hdr/fingerprints/HDRCapabilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/HDRCapabilityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.video.hdr.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.util.fingerprint.MethodReferenceNameFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt index 4d224c251..4dec570e3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedChangedFromRecyclerViewFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.video.speed.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedInitializeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedInitializeFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedInitializeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedInitializeFingerprint.kt index ef929dfed..b750f4bc0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/fingerprints/PlaybackSpeedInitializeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/PlaybackSpeedInitializeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.video.speed.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt similarity index 93% rename from src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt index 76cdc4d88..a317ae503 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualityChangedFromRecyclerViewFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualitySetterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualitySetterFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualitySetterFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualitySetterFingerprint.kt index 53689d9f0..f626f4bb1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/QualitySetterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playback/fingerprints/QualitySetterFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.fingerprints +package app.revanced.patches.youtube.video.playback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt deleted file mode 100644 index fbd650dc2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt +++ /dev/null @@ -1,92 +0,0 @@ -package app.revanced.patches.youtube.video.quality - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patches.youtube.utils.fingerprints.QualityChangedFromRecyclerViewFingerprint -import app.revanced.patches.youtube.utils.fingerprints.QualitySetterFingerprint -import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.patches.youtube.video.videoid.VideoIdPatch -import app.revanced.util.copyXmlNode -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object VideoQualityPatch : BaseBytecodePatch( - name = "Default video quality", - description = "Adds an option to set the default video quality.", - dependencies = setOf( - PlayerTypeHookPatch::class, - SettingsPatch::class, - ShortsPlaybackPatch::class, - VideoIdPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - QualityChangedFromRecyclerViewFingerprint, - QualitySetterFingerprint - ) -) { - private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = - "$VIDEO_PATH/VideoQualityPatch;" - private const val INTEGRATIONS_RELOAD_VIDEO_CLASS_DESCRIPTOR = - "$VIDEO_PATH/ReloadVideoPatch;" - - override fun execute(context: BytecodeContext) { - - // Remember video quality from recyclerview (litho view). - QualityChangedFromRecyclerViewFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val index = it.scanResult.patternScanResult!!.startIndex - - addInstruction( - index + 1, - "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" - ) - - } - } - - QualitySetterFingerprint.resultOrThrow().let { - val onItemClickMethod = - it.mutableClass.methods.find { method -> method.name == "onItemClick" } - - onItemClickMethod?.apply { - addInstruction( - 0, - "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" - ) - } ?: throw PatchException("Failed to find onItemClick method") - } - - VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_RELOAD_VIDEO_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") - - /** - * Copy arrays - */ - contexts.copyXmlNode("youtube/quality/host", "values/arrays.xml", "resources") - - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: VIDEO_SETTINGS", - "SETTINGS: VIDEO_EXPERIMENTAL_FLAGS", - "SETTINGS: DEFAULT_VIDEO_QUALITY" - ) - ) - - SettingsPatch.updatePatchStatus("Default video quality") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt deleted file mode 100644 index 72e133eb5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt +++ /dev/null @@ -1,107 +0,0 @@ -package app.revanced.patches.youtube.video.speed - -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.patches.youtube.utils.fingerprints.QualityChangedFromRecyclerViewFingerprint -import app.revanced.patches.youtube.utils.fingerprints.VideoEndFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch.speedSelectionInsertMethod -import app.revanced.patches.youtube.video.speed.fingerprints.PlaybackSpeedChangedFromRecyclerViewFingerprint -import app.revanced.patches.youtube.video.speed.fingerprints.PlaybackSpeedInitializeFingerprint -import app.revanced.util.getTargetIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import app.revanced.util.updatePatchStatus -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object PlaybackSpeedPatch : BaseBytecodePatch( - name = "Default playback speed", - description = "Adds an option to set the default playback speed.", - dependencies = setOf( - SettingsPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - QualityChangedFromRecyclerViewFingerprint, - VideoEndFingerprint - ) -) { - private const val INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR = - "$VIDEO_PATH/PlaybackSpeedPatch;" - - override fun execute(context: BytecodeContext) { - - PlaybackSpeedChangedFromRecyclerViewFingerprint.resolve( - context, - QualityChangedFromRecyclerViewFingerprint.resultOrThrow().classDef - ) - - val newMethod = PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod - - arrayOf( - newMethod, - speedSelectionInsertMethod - ).forEach { - it.apply { - val speedSelectionValueInstructionIndex = getTargetIndex(Opcode.IGET) - val speedSelectionValueRegister = - getInstruction(speedSelectionValueInstructionIndex).registerA - - addInstruction( - speedSelectionValueInstructionIndex + 1, - "invoke-static {v$speedSelectionValueRegister}, " + - "$INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->userSelectedPlaybackSpeed(F)V" - ) - } - } - - VideoEndFingerprint.resultOrThrow().let { parentResult -> - PlaybackSpeedInitializeFingerprint.also { - it.resolve( - context, - parentResult.classDef - ) - }.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeedInShorts(F)F - move-result v$insertRegister - """ - ) - } - } - } - - VideoInformationPatch.cpnHook("$INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Z)V") - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: VIDEO_SETTINGS", - "SETTINGS: VIDEO_EXPERIMENTAL_FLAGS", - "SETTINGS: DEFAULT_PLAYBACK_SPEED" - ) - ) - - SettingsPatch.updatePatchStatus("Default playback speed") - - context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "DefaultPlaybackSpeed") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index df5412453..04975e0be 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -5,14 +5,18 @@ package app.revanced.util 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.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprintResult import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableField +import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.Method @@ -23,6 +27,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.Reference +import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.util.MethodUtil fun MethodFingerprint.resultOrThrow() = result ?: throw exception @@ -359,6 +364,57 @@ fun MutableMethod.getWalkerMethod(context: BytecodeContext, index: Int) = .nextMethod(index, true) .getMethod() as MutableMethod +fun MutableClass.addFieldAndInstructions( + context: BytecodeContext, + methodName: String, + fieldName: String, + objectClass: String, + smaliInstructions: String, + shouldAddConstructor: Boolean +) { + val objectCall = "$this->$fieldName:$objectClass" + + methods.single { method -> method.name == methodName }.apply { + staticFields.add( + ImmutableField( + definingClass, + fieldName, + objectClass, + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + annotations, + null + ).toMutable() + ) + + addInstructionsWithLabels( + 0, + """ + sget-object v0, $objectCall + """ + smaliInstructions + ) + } + + if (shouldAddConstructor) { + context.findClass(objectClass)!!.mutableClass.methods + .filter { method -> MethodUtil.isConstructor(method) } + .forEach { mutableMethod -> + mutableMethod.apply { + val initializeIndex = getTargetIndexWithMethodReferenceName("") + val insertIndex = if (initializeIndex == -1) + 1 + else + initializeIndex + 1 + + addInstruction( + insertIndex, + "sput-object p0, $objectCall" + ) + } + } + } +} + fun BytecodeContext.updatePatchStatus( className: String, methodName: String diff --git a/src/main/resources/youtube/alternativethumbnails/host/values/arrays.xml b/src/main/resources/youtube/alternativethumbnails/host/values/arrays.xml deleted file mode 100644 index f2c8ef755..000000000 --- a/src/main/resources/youtube/alternativethumbnails/host/values/arrays.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - @string/revanced_alt_thumbnail_stills_time_entry_1 - @string/revanced_alt_thumbnail_stills_time_entry_2 - @string/revanced_alt_thumbnail_stills_time_entry_3 - - - 1 - 2 - 3 - - diff --git a/src/main/resources/youtube/doubleback/host/values/arrays.xml b/src/main/resources/youtube/doubleback/host/values/arrays.xml deleted file mode 100644 index cc7d2348b..000000000 --- a/src/main/resources/youtube/doubleback/host/values/arrays.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - 0 - 1 - 2 - 3 - - - 0 - 1 - 2 - 3 - - diff --git a/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml b/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml index df2983ba3..fd7f228c3 100644 --- a/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml +++ b/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml @@ -2,20 +2,20 @@ NewPipe - NewPipe x SponsorBlock Seal + Tubular YTDLnis org.schabi.newpipe - org.polymorphicshade.newpipe com.junkfood.seal + org.polymorphicshade.tubular com.deniscerri.ytdl https://github.com/TeamNewPipe/NewPipe/releases/latest - https://github.com/polymorphicshade/NewPipe/releases/latest https://github.com/JunkFood02/Seal/releases/latest + https://github.com/polymorphicshade/Tubular/releases/latest https://github.com/deniscerri/ytdlnis/releases/latest diff --git a/src/main/resources/youtube/quality/host/values/arrays.xml b/src/main/resources/youtube/quality/host/values/arrays.xml deleted file mode 100644 index adc399d5e..000000000 --- a/src/main/resources/youtube/quality/host/values/arrays.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - @string/quality_auto - 144p - 240p - 360p - 480p - 720p - 1080p - 1440p - 2160p - - - -2 - 144 - 240 - 360 - 480 - 720 - 1080 - 1440 - 2160 - - diff --git a/src/main/resources/youtube/settings/host/values/arrays.xml b/src/main/resources/youtube/settings/host/values/arrays.xml new file mode 100644 index 000000000..3e2bddf01 --- /dev/null +++ b/src/main/resources/youtube/settings/host/values/arrays.xml @@ -0,0 +1,81 @@ + + + + @string/revanced_alt_thumbnail_stills_time_entry_1 + @string/revanced_alt_thumbnail_stills_time_entry_2 + @string/revanced_alt_thumbnail_stills_time_entry_3 + + + 1 + 2 + 3 + + + @string/revanced_change_start_page_entry_default + @string/revanced_change_start_page_entry_search + @string/revanced_change_start_page_entry_subscriptions + @string/revanced_change_start_page_entry_explore + @string/revanced_change_start_page_entry_shorts + @string/revanced_change_start_page_entry_library + @string/revanced_change_start_page_entry_liked_videos + @string/revanced_change_start_page_entry_history + @string/revanced_change_start_page_entry_trending + + + + + open.search + open.subscriptions + open.explore + open.shorts + + www.youtube.com/feed/library + www.youtube.com/playlist?list=LL + www.youtube.com/feed/history + www.youtube.com/feed/trending + + + @string/revanced_change_shorts_repeat_state_entry_default + @string/revanced_change_shorts_repeat_state_entry_repeat + @string/revanced_change_shorts_repeat_state_entry_auto_play + @string/revanced_change_shorts_repeat_state_entry_pause + + + 0 + 1 + 2 + 3 + + + @string/quality_auto + 144p + 240p + 360p + 480p + 720p + 1080p + 1440p + 2160p + + + -2 + 144 + 240 + 360 + 480 + 720 + 1080 + 1440 + 2160 + + + @string/revanced_spoof_app_version_target_entry_18_17_43 + @string/revanced_spoof_app_version_target_entry_18_05_40 + @string/revanced_spoof_app_version_target_entry_17_41_37 + + + 18.17.43 + 18.05.40 + 17.41.37 + + diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 4ad60e2c3..0dac74a17 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -1,493 +1,222 @@ - GmsCore does not have permission to run in the background. - GmsCore is not whitelisted from battery optimization. - Action needed - Enable cloud messaging to receive notifications. - Open GmsCore - GmsCore is not installed. Install it. - "Follow the 'Don't kill my app' guide for GmsCore." + + ReVanced Extended - Ads - Alternative thumbnails + + Experimental Flags + Restart to load the layout normally + Refresh and restart + Normal + + + Ads + + Hide fullscreen ads + Fullscreen ads are hidden. + Fullscreen ads are shown. + Hide general ads + General ads are hidden. + General ads are shown. + Hide merchandise shelf + Merchandise shelves are hidden. + Merchandise shelves are shown. + Hide paid promotion banner + Paid promotion banner is hidden. + Paid promotion banner is shown. + Hide self sponsored cards + Self sponsored cards are hidden. + Self sponsored cards are shown. + Hide video ads + Video ads are hidden. + Video ads are shown. + Hide view products banner + View products banner is hidden. + View products banner is shown. + Hide web search results + Web search results are hidden. + Web search results are shown. + Hide YouTube Premium promotion + YouTube Premium promotion is hidden. + YouTube Premium promotion is shown. + + + + Alternative thumbnails + + Thumbnails in use "Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then the original YouTube thumbnails are shown." "Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then still video captures are shown." Showing original YouTube thumbnails. Showing still video captures. - Thumbnails in use + + + DeArrow + Enable DeArrow thumbnails + Using DeArrow thumbnails. + Not using DeArrow thumbnails. + Show a toast if API is not available + Toast is shown if DeArrow is not available. + Toast is not shown if DeArrow is not available. + DeArrow API endpoint + "The URL of the DeArrow thumbnail cache endpoint. Do not change this unless you know what you're doing." + About DeArrow "DeArrow provides crowd-sourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube. If enabled, video URLs will be sent to the API server and no other data is sent. Tap here to learn more about DeArrow." - About DeArrow - "The URL of the DeArrow thumbnail cache endpoint. Do not change this unless you know what you're doing." - DeArrow API endpoint - Toast is not shown if DeArrow is not available. - Toast is shown if DeArrow is not available. - Show a toast if API is not available - DeArrow temporarily not available. (status code: %s) - DeArrow temporarily not available. - Not using DeArrow thumbnails. - Using DeArrow thumbnails. - Enable DeArrow thumbnails - Video thumbnail settings. - Alternative thumbnails - Still video captures - Still captures are taken from the beginning / middle / end of each video. These images are built into YouTube and no external API is used. - About still video captures - Using high quality still captures. - Using medium quality still captures. Thumbnails will load faster, but live streams, unreleased, and very old videos may show blank thumbnails. - Use fast still captures - Not using YouTube still video captures. + + + Still video captures + Enable still video captures Using YouTube still video captures. + Not using YouTube still video captures. + Video time to take the still from Beginning of video Middle of video End of video - Video time to take the still from - Enable still video captures - Append time stamp information is disabled. - Append time stamp information is enabled. - Append time stamp information - Append playback speed. - Append video quality. - Append information type - Description panel is expanded manually. - Description panel is always expanded. - Always expand panel - Bottom player - Button container - Ambient mode is disabled in battery saver mode. - Ambient mode is enabled in battery saver mode. - Bypass ambient mode restrictions - Autoplay - Default - Pause - Repeat - Change shorts repeat state - Switch toggles are used. - Text toggles are used. - Change toggle type - Default - Explore - History - Library - Liked videos - Search - Shorts - Subscriptions - Trending - Change start page - Invalid start page, resetting to default. - Channel bar - Channel profile - Comments - List of component path builder strings to filter separated by new line. - Edit custom filter - Invalid custom filter: %s. - Custom filter is disabled. - Custom filter is enabled. - Enable custom filter - Invalid custom playback speeds. Reset to default values. - Add or change available playback speeds. - Edit custom playback speeds - Custom speeds can\'t be more than %sx. Reset to default values. - Old style flyout panel is used. - Custom dialog is used. - Custom playback speed panel type - Opacity value between 0-100, where 0 is transparent. - Custom player overlay opacity - Player overlay opacity must be between 0-100. Reset to default values. - Type the hex code of the seekbar color. - Custom seekbar color value - To open RVX in an external browser, turn on \'Open supported links\' and enable supported web addresses. - Open default app settings - Default playback speed - Default video quality on Mobile network - Default video quality on Wi-Fi network - Description - Disables ambient mode in fullscreen. - Disable ambient mode in fullscreen - Always disable ambient mode. - Disable ambient mode - Forced auto captions are enabled. - Forced auto captions are disabled. - Disable forced auto captions - "Disables the following interactions when the description panel is expanded: + Use fast still captures + Using medium quality still captures. Thumbnails will load faster, but live streams, unreleased, and very old videos may show blank thumbnails. + Using high quality still captures. + About still video captures + Still captures are taken from the beginning / middle / end of each video. These images are built into YouTube and no external API is used. -• Tap to scroll. -• Tap and hold to select text." - Disable description interaction - Default playback speed is enabled in live stream. - Default playback speed is disabled in live stream. - Disable playback speed in live stream - Haptic feedback is enabled. - Haptic feedback is disabled. - Disable chapters haptic feedback - Disable scrubbing haptic feedback - Disable seek haptic feedback - Disable seek undo haptic feedback - Disable zoom haptic feedback - Auto HDR brightness is enabled. - Auto HDR brightness is disabled. - Disable auto HDR brightness - HDR video is enabled. - HDR video is disabled. - Disable HDR video - Landscape mode when entering fullscreen is enabled. - Landscape mode when entering fullscreen is disabled. - Disable landscape mode - "Disable CronetEngine's QUIC protocol." - Disable QUIC protocol - Shorts player will resume on app startup - Shorts player will not resume on app startup - Disable resuming Shorts player - "Disable 'Playing at 2x speed' while holding down. + + DeArrow temporarily not available. (status code: %s) + DeArrow temporarily not available. -Note: Disabling the speed overlay restores the 'Slide to seek' behavior of the old layout." - Disable speed overlay - The amount of seconds the double press back to exit. - Double back timeout - Entering fullscreen when swiping down below the video player is disabled. - Entering fullscreen when swiping down below the video player is enabled. - Enable bottom player gestures - Compact controls overlay is disabled. - Compact controls overlay is enabled. - Enable compact controls overlay - Custom playback speed is disabled. - Custom playback speed is enabled. - Enable custom playback speed - Custom seekbar color is disabled. - Custom seekbar color is enabled. - Enable custom seekbar color - Debug logs do not include buffer. - Debug logs include buffer. - Enable debug buffer logging - Debug logs are disabled. - Debug logs are enabled. - Enable debug logging - Default playback speed does not apply to Shorts. - Default playback speed applies to Shorts. - Enable shorts default playback speed - External browser is disabled. - External browser is enabled. - Enable external browser - Gradient loading screen is disabled. - Gradient loading screen is enabled. - Enable gradient loading screen - Language switch is disabled. - Language switch is enabled. - Enable language switch - New splash animation is disabled. - New splash animation is enabled. - Enable new splash animation - New thumbnail preview is disabled. - New thumbnail preview is enabled. - Enable new thumbnail preview - New style quality options are shown. - Old style quality options are shown. - Enable old style quality layout - Following default redirect policy. - Bypassing URL redirects. - Enable open links directly - Apply opus audio codec instead of mp4a audio codec. - Enable opus codec - Tricks the dpi to use some phone layouts. - Enable phone layout - Does not save playback speed values even when changing playback speed. - Save the playback speed value whenever you change the playback speed. - Enable save playback speed - Does not save video quality values even when changing video quality. - Save the video quality value whenever you change the video quality. - Enable save video quality - Seekbar tapping is disabled. - Seekbar tapping is enabled. - Enable seekbar tapping - Song search is disabled. - Song search is enabled. - Enable song search - Even if the brightness is set to 0 by swiping, auto brightness is not activated. - When brightness reaches 0 by swiping, auto brightness is activated. - Enable auto-brightness by swiping - Brightness swipe is disabled. - Brightness swipe is enabled. - Enable brightness gesture - Haptic feedback is disabled. - Haptic feedback is enabled. - Enable haptic feedback - Touch to activate swipe gesture. - Touch and hold to activate swipe gesture. - Enable press-to-swipe gesture - Volume swipe is disabled. - Volume swipe is enabled. - Enable volume gesture - Tricks the dpi to use some tablet layouts. - Enable tablet layout - Tablet mini player is disabled. - Tablet mini player is enabled. - Enable tablet mini player - Tablet navigation bar is disabled. - Tablet navigation bar is enabled. - Enable tablet navigation bar - Spoof device information to enable video codec. - Enable video codec - VP9 codec is enabled. - HDR codec is enabled. - Video codec type - Wide search bar is disabled. - Wide search bar is enabled. - Enable wide search bar - "Enabling this setting will disable the settings button in the You tab. -In this case, please use the following path: -You tab > View channel > Menu > Settings." - Enable wide search bar in You tab - Experimental Flags - Failed to export settings. - Settings were successfully exported. - Export settings to file. - Export settings - Import - Copy - Import / Export as file - Import or export settings as text. - Import / Export as text - Import or export settings. - Import / Export settings - Failed to import settings. - Settings reset to default. - Settings were successfully imported. - Import settings from saved file. - Import settings - Reset - Download app - Installed - Not installed - %s is not installed. Please install it. - Package name of your installed external downloader app, such as NewPipe or YTDLnis. - External downloader package name - Set as default downloader - Settings for using an external downloader. - External downloader settings - Feed flyout panel - Flyout menu - "Videos will be switched to fullscreen in the following situations: + + Feed -• When a timestamp in the comments is clicked on. -• When a video is started." - Force fullscreen - Fullscreen - General - Haptic feedback - Edit account menu filter - "Hide elements of the account menu and You tab. -Some components may not be hidden." - Hide account menu - Album cards are shown. - Album cards are hidden. Hide album cards - Audio track button is shown. - Audio track button is hidden. - Hide audio track button - Autoplay button is shown. - Autoplay button is hidden. - Hide autoplay button - Autoplay preview container is shown. - Autoplay preview container is hidden. - Hide autoplay preview container - Auto player popup panels are shown. - Auto player popup panels are hidden. - Hide auto player popup panels - Browse store button is shown. - Browse store button is hidden. - Hide browse store button - Clip button is shown. - Clip button is hidden. - Hide clip button - Dislike button is shown. - Dislike button is hidden. - Hide dislike button - Download button is shown. - Download button is hidden. - Hide download button - Like and dislike buttons are shown. - Like and dislike buttons are hidden. - Hide like and dislike buttons - Like button is shown. - Like button is hidden. - Hide like button - Live chat button is shown. - Live chat button is hidden. - Hide live chat button - Open mix playlist button is shown. - Open mix playlist button is hidden. - Hide open mix playlist button - Open playlist button is shown. - Open playlist button is hidden. - Hide open playlist button - Remix button is shown. - Remix button is hidden. - Hide remix button - Report button is shown. - Report button is hidden. - Hide report button - Rewards button is shown. - Rewards button is hidden. - Hide rewards button - Save to playlist button is shown. - Save to playlist button is hidden. - Hide save to playlist button - Share button is shown. - Share button is hidden. - Hide share button - Shop button is shown. - Shop button is hidden. - Hide shop button - Thanks button is shown. - Thanks button is hidden. - Hide thanks button - Captions button is shown. - Captions button is hidden. - Hide captions button - Cast button is shown. - Cast button is hidden. - Hide cast button - Hide category bar in feed - Hide category bar in related video - Hide category bar in search results - Category bar is shown. - Category bar is hidden. - Channel guidelines are shown. - Channel guidelines are hidden. - Hide channel guidelines - Channel avatar section of the subscriptions feed is shown. - Channel avatar section of the subscriptions feed is hidden. - Hide channel avatar section - Channel member shelf is shown. - Channel member shelf is hidden. - Hide channel member shelf - Links at the top of channel profile is shown. - Links at the top of channel profile is hidden. - Hide channel profile links - Channel watermark is shown. - Channel watermark is hidden. - Hide channel watermark - Chapters are shown. - Chapters are hidden. - Hide chapters - Chips shelf is shown. - Chips shelf is hidden. + Album cards are hidden. + Album cards are shown. + "Hides following shelves: +• Breaking news +• Continue watching +• Explore more channels +• Listen again +• Shopping +• Watch it again" + Hide carousel shelf Hide chips shelf - Collapse button is shown. - Collapse button is hidden. - Hide collapse button - Comments by members banner is shown. - Comments by members banner is hidden. - Hide comments by members banner - Comments section is shown. - Comments section is hidden. - Hide comments section - Community posts in home feed are shown. - Community posts in home feed are hidden. - Hide community posts in home feed - Community posts in subscriptions feed are shown. - Community posts in subscriptions feed are hidden. - Hide community posts in subscriptions feed - Create button in navigation bar is shown. - Create button in navigation bar is hidden. - Hide create button - Create shorts button is shown. - Create shorts button is hidden. - Hide create shorts button - Crowdfunding box is shown. - Crowdfunding box is hidden. - Hide crowdfunding box - Emoji picker and time stamp are shown. - Emoji picker and time stamp are hidden. - Hide emoji picker and time stamp - End screen cards are shown. - End screen cards are hidden. - Hide end screen cards - End screen overlay is shown. - End screen overlay is hidden. - Hide end screen overlay - Expandable chips are shown. - Expandable chips are hidden. + Chips shelf is hidden. + Chips shelf is shown. Hide expandable chip under videos - Edit feed flyout filter - Feed flyout filter is disabled. - Feed flyout filter is enabled. - Hide feed flyout components - Feed surveys are shown. - Feed surveys are hidden. + Expandable chips are hidden. + Expandable chips are shown. + Hide feed search bar + Feed search bar is hidden. + Feed search bar is shown. Hide feed surveys - Film strip overlay is shown. - Film strip overlay is hidden. - Hide film strip overlay - Floating microphone button is shown. - Floating microphone button is hidden. - Hide floating microphone button - "'For You' shelves are shown." - "'For You' shelves are hidden." - "Hide 'For You' shelf" - Fullscreen ads are shown. - Fullscreen ads are hidden. - Hide fullscreen ads - Fullscreen button is shown. - Fullscreen button is hidden. - Hide fullscreen button - Fullscreen panels are shown. - Fullscreen panels are hidden. - Hide fullscreen panels - Game sections are shown. - Game sections are hidden. - Hide game sections - General ads are shown. - General ads are hidden. - Hide general ads - YouTube Premium promotion is shown. - YouTube Premium promotion is hidden. - Hide YouTube Premium promotion - Gray description is shown. - Gray description is hidden. - Hide gray description - Gray separators are shown. - Gray separators are hidden. - Hide gray separator - Handle is shown. - Handle is hidden. - Hide handle - Home button in navigation bar is shown. - Home button in navigation bar is hidden. - Hide home button - Image shelves are shown. - Image shelves are hidden. + Feed surveys are hidden. + Feed surveys are shown. Hide image shelf - Info cards sections are shown. - Info cards sections are hidden. - Hide info cards sections - Info cards are shown. - Info cards are hidden. - Hide info cards - Info panels are shown. - Info panels are hidden. - Hide info panels - Join button is shown. - Join button is hidden. - Hide join button + Image shelves are hidden. + Image shelves are shown. + Hide latest posts + Latest posts are hidden. + Latest posts are shown. + "Hide 'Latest videos' button" + "'Latest videos' button is hidden." + "'Latest videos' button is shown." + Hide mix playlist + Mix playlist is hidden. + Mix playlist is shown. + Hide movies shelf + Movies shelves are hidden. + Movies shelves are shown. + "Hide 'Notify me' button" + "'Notify me' button is hidden." + "'Notify me' button is shown." + "Hide 'Show more' button" + "'Show more' button is hidden." + "'Show more' button is shown." + Hide subscriptions channel section + Subscriptions channel section is hidden. + Subscriptions channel section is shown. + Hide ticket shelf + Ticket shelves are hidden. + Ticket shelves are shown. - - Hide keyword content - Hide search and feed videos using keyword filters. + + Category bar + Hide or show the category bar in the feed, search, and related videos. + + Hide in feed + Hidden in feed. + Shown in feed. + Hide in related videos + Hidden in related videos. + Shown in related videos. + Hide in search + Hidden in search. + Shown in search. + + + Channel profile + Hide or show components in the channel profile. + + Hide browse store button + Browse store button is hidden. + Browse store button is shown. + Hide channel member shelf + Channel member shelf is hidden. + Channel member shelf is shown. + Hide channel profile links + Links at the top of channel profile is hidden. + Links at the top of channel profile is shown. + "Hide 'For You' shelf" + "'For You' shelves are hidden." + "'For You' shelves are shown." + Hide store tab + Store tab is hidden. + Store tab is shown. + + + Community posts + Hide or show community posts in the feed and channel. + + Hide in channel + Hidden in channel. + Shown in channel. + Hide in home feed and related videos + Hidden in home feed and related videos. + Shown in home feed and related videos. + Hide in subscriptions feed + Hidden in subscriptions feed. + Shown in subscriptions feed. + + + Flyout menu + Hide or show flyout menu in the feed. + + Enable feed flyout menu filter + Feed flyout menu filter is enabled. + Feed flyout menu filter is disabled. + Feed flyout menu filter + List of flyout menu names to filter separated by a new line. + + + Video filter + Hide videos by keywords or views. + + + Keyword filter Hide home videos by keywords - Videos in the home tab are filtered by keywords. - Videos in the home tab are not filtered by keywords. - Hide subscription videos by keywords - Videos in the subscriptions tab are filtered by keywords. - Videos in the subscriptions tab are not filtered by keywords. + Videos in home feed are filtered. + Videos in home feed are not filtered. Hide search results by keywords - Search results are filtered by keywords. - Search results are not filtered by keywords. + Search results are filtered. + Search results are not filtered. + Hide subscription videos by keywords + Videos in subscriptions feed are filtered. + Videos in subscriptions feed are not filtered. + Hide comments by keywords + Comments are filtered. + Comments are not filtered. Keywords to hide "Keywords and phrases to hide, separated by new lines. Words with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)." @@ -501,392 +230,775 @@ Limitations: Invalid keyword. Cannot use: \'%s\' as a filter Invalid keyword. \'%1$s\' is less than %2$d characters + + Recommended video + Hide recommended videos + "Hides following recommended videos: - Latest posts are shown. - Latest posts are hidden. - Hide latest posts - Latest videos button is shown. - Latest videos button is hidden. - Hide latest videos button - Library button in navigation bar is shown. - Library button in navigation bar is hidden. - Hide library button - Load more button is shown. - Load more button is hidden. - Hide load more button - Medical panels are shown. - Medical panels are hidden. - Hide medical panels - Merchandise shelves are shown. - Merchandise shelves are hidden. - Hide merchandise shelf - Mix playlist is shown. - Mix playlist is hidden. - Hide mix playlist - Movies shelves are shown. - Movies shelves are hidden. - Hide movies shelf - Music sections are shown. - Music sections are hidden. - Hide music sections - Navigation label is shown. - Navigation label is hidden. - Hide navigation label - Notifications button in navigation bar is shown. - Notifications button in navigation bar is hidden. - Hide notifications button - Notify me button is shown. - Notify me button is hidden. - Hide notify me button in feed - Paid promotion banner is shown. - Paid promotion banner is hidden. - Hide paid promotion banner - Place sections are shown. - Place sections are hidden. - Hide place sections - Ambient mode menu is shown. - Ambient mode menu is hidden. - Hide ambient mode menu - Audio track menu is shown. - Audio track menu is hidden. - Hide audio track menu - Captions menu footer is shown. - Captions menu footer is hidden. - Hide captions menu footer - Captions menu is shown. - Captions menu is hidden. - Hide captions menu - Help & feedback menu is shown. - Help & feedback menu is hidden. - Hide help & feedback menu - Listen with YouTube Music menu is shown. - Listen with YouTube Music menu is hidden. - Hide listen with YouTube Music menu - Lock screen menu is shown. - Lock screen menu is hidden. - Hide lock screen menu - Loop video menu is shown. - Loop video menu is hidden. - Hide loop video menu - More information menu is shown. - More information menu is hidden. - Hide more information menu - Playback speed menu is shown. - Playback speed menu is hidden. - Hide playback speed menu - Premium controls menu is shown. - Premium controls menu is hidden. - Hide premium controls menu - Quality menu footer is shown. - Quality menu footer is hidden. - Hide quality menu footer - Report menu is shown. - Report menu is hidden. - Hide report menu - Stable volume menu is shown. - Stable volume menu is hidden. - Hide stable volume menu - Stats for nerds menu is shown. - Stats for nerds menu is hidden. - Hide stats for nerds menu - Watch in VR menu is shown. - Watch in VR menu is hidden. - Hide watch in VR menu - Podcast sections are shown. - Podcast sections are hidden. - Hide podcast sections - Preview comment is shown. - Preview comment is hidden. - Hide preview comment - This changes the size of the comment section, so it is impossible to open a live chat replay in the comment section. - This does not change the size of the comment section, so it is possible to open the live chat replay in the comment section. - Hide preview comment type - Buttons are shown. - Buttons are hidden. - Hide previous & next button - Comment button is shown. - Comment button is hidden. - Hide comment button - More button is shown. - More button is hidden. - Hide more button - Related videos are shown. - Related videos are hidden. - Hide related videos in quick actions - Quick actions container is shown. - Quick actions container is hidden. - Hide quick actions container - Search bar is shown. - Search bar is hidden. - Hide search bar in home feed - Thumbnails in the search term history are shown. - Thumbnails in the search term history are hidden. +• Videos with 'Only for Membership' tag +• Videos with the phrases such as 'People also watched' at the bottom of the video +• Videos uploaded from channels not subscribed to that have less than 1,000 views" + + + View count filter + Hide recommended videos by views + Hide recommended videos with less than a specified number of views. + Number of views + Recommended videos with views less than this number will be hidden. + View keys + Specify your language template for the number of views shown under each video in the user interface. Each key (a letter/word in your language) -> value (meaning of the key) must be on a new line. Keys go before "->" sign. If you switch app or system language you have to reset this setting.\n\nExamples:\nEnglish: 10K views = K -> 1000, views -> views\nSpanish: 10 K vistas = K -> 1000, vistas -> views + K -> 1 000\nM -> 1 000 000\nB -> 1 000 000 000\nviews -> views + + + + General + + Change start page + Default + Explore + History + Library + Liked videos + Search + Shorts + Subscriptions + Trending + Invalid start page, resetting to default. + Disable forced auto captions + Forced auto captions are disabled. + Forced auto captions are enabled. + Disable splash animation + Splash animation is disabled. + Splash animation is enabled. + Enable gradient loading screen + Gradient loading screen is enabled. + Gradient loading screen is disabled. + Enable tablet mini player + Tablet mini player is enabled. + Tablet mini player is disabled. + Enable wide search bar + Wide search bar is enabled. + Wide search bar is disabled. + Enable wide search bar in You tab + "Enabling this setting will disable the settings button in the You tab. + +In this case, please use the following path: +You tab > View channel > Menu > Settings." + Hide cast button + Cast button is hidden. + Cast button is shown. + Hide floating microphone button + Floating microphone button is hidden. + Floating microphone button is shown. + Hide gray separator + Gray separators are hidden. + Gray separators are shown. Hide search term thumbnail - Video player seekbar is shown. - Video player seekbar is hidden. - Thumbnail seekbar is shown. - Thumbnail seekbar is hidden. - Hide seekbar in video thumbnails - Hide seekbar in video player - Seek message is shown. - Seek message is hidden. - Hide seek message - Seek undo message is shown. - Seek undo message is hidden. - Hide seek undo message - Self sponsored cards are shown. - Self sponsored cards are hidden. - Hide self sponsored cards - Shopping links are shown. - Shopping links are hidden. - Hide shopping links - Shorts button in navigation bar is shown. - Shorts button in navigation bar is hidden. - Hide shorts button - Hides Shorts section or the Shorts player component. - Hide shorts component - Comments button is shown. - Comments button is hidden. - Hide comments button - Navigation bar is shown. - Navigation bar is hidden. - Hide navigation bar - Pivot button is shown. - Pivot button is hidden. - Hide pivot button - Subscriptions button is shown. - Subscriptions button is hidden. - Hide subscriptions button - Shorts shelves in watch history is hidden. - Shorts shelves in watch history is shown. - Show in watch history - "Hides Shorts shelves. - -Known issue: Official headers in search results will be hidden." - Hide shorts shelf - Banner is shown. - Banner is hidden. - Hide banner - Camera button is shown. - Camera button is hidden. - Hide camera button - Menu button is shown. - Menu button is hidden. - Hide menu button - Search button is shown. - Search button is hidden. - Hide search button - Snack bar is shown. - Snack bar is hidden. + Thumbnails in the search term history are hidden. + Thumbnails in the search term history are shown. Hide snack bar - Start trial button is shown. - Start trial button is hidden. - Hide start trial button - Store tab is shown. - Store tab is hidden. - Hide store tab - Subscriptions button in navigation bar is shown. - Subscriptions button in navigation bar is hidden. - Hide subscriptions button - Suggested actions shown. - Suggested actions hidden. - Hide suggested actions - "This setting has been deprecated. - -Instead, use the 'Settings → Autoplay → Autoplay next video' setting." - Hide suggested video end screen - "Hides following shelves: -• Breaking news -• Continue watching -• Explore more channels -• Listen again -• Shopping -• Watch it Again" - Hide suggestions shelf - Ticket shelves are shown. - Ticket shelves are hidden. - Hide ticket shelf - Timed reactions are shown. - Timed reactions are hidden. - Hide timed reactions - Time stamp is shown. - Time stamp is hidden. - Hide time stamp - Transcript sections are shown. - Transcript sections are hidden. - Hide transcript sections - Create and Notification buttons are shown. - Create and Notification buttons are hidden. + Snack bar is hidden. + Snack bar is shown. Hide buttons in toolbar - Trending searches are shown. - Trending searches are hidden. + Create and Notification buttons are hidden. + Create and Notification buttons are shown. Hide trending searches - Video ads are shown. - Video ads are hidden. - Hide video ads - "Hide videos with gray description from search results. -Videos with a gray description include videos that are not related to search terms." - Hide videos with gray description - "Hide videos with less than 1,000 views exposed to the home feed. -Some videos, including those from channels you subscribe to, may not be hidden even if they have fewer than 1,000 views." - Hide videos with low views - View products banner is shown. - View products banner is hidden. - Hide view products banner - Web search results are shown. - Web search results are hidden. - Hide web search results - YouTube Music button is shown. - YouTube Music button is hidden. - Hide youtube music button - "Replace download button with external download button." - Hook download button - Inform - Keeps landscape mode when turning the screen off and on in fullscreen. - The amount of milliseconds the landscape mode is forced. - Keep landscape mode timeout - Keep landscape mode - Layout - Miscellaneous - Navigation - Others - Overlay button - Tap to toggle always repeat states. - Show always repeat button - "Tap to copy video URL. -Tap and hold to copy video URL with timestamp." - "Tap to copy video URL with timestamp. -Tap and hold to copy video timestamp." - Show copy timestamp URL button - Show copy video URL button - Tap to launch external downloader. - Show external download button - Playback speed reseted (1.0x). - "Tap to open speed dialog. -Tap and hold to set playback speed to 1.0x." - Show speed dialog button - Patches Information - Information about applied patches. - Normal - Player - To hide the additional settings menu, hide all settings in the additional settings category. - Player flyout panel (Additional settings) - Player flyout panel - Configure the spacing from the seekbar to the quick action container, between 0-64. - Quick actions top margin - Quick actions top margin must be between 0-64. Reset to default values. - Quick actions + Trending searches are hidden. + Trending searches are shown. + Remove viewer discretion dialog "Remove viewer discretion dialog. This does not bypass the age restriction. It just accepts it automatically." - Remove viewer discretion dialog - Restart to load the layout normally - Refresh and restart - About - Dislike data is provided by the Return YouTube Dislike API. Tap here to learn more. - Like button styled for best appearance. - Like button styled for minimum width. - Compact like button - Dislikes shown as number. - Dislikes shown as percentage. - Dislikes as percentage - Dislikes are not shown. - Dislikes are shown. - Enable Return YouTube Dislike - Dislikes temporarily not available (API timed out). - Dislikes not available (status %d). - Dislikes not available (client API limit reached). - Dislikes not available (%s). - Limitation: Dislikes may not appear in certain situations. - Dislikes hidden on Shorts. - Dislikes shown on Shorts. %s - Show dislikes on Shorts - Show a toast if API is not available - Toast is not shown if Return YouTube Dislike is not available. - Toast is shown if Return YouTube Dislike is not available. - Hidden - - Removes tracking query parameters from the URLs when sharing links. - Sanitize sharing links - Changing default speed to %s. - Changing default mobile data quality to %s. - Failed to set quality. - Changing default Wi-Fi quality to %s. - Seekbar - Settings copied to clipboard. - Time stamp copied to clipboard. (%s) - URL copied to clipboard. - URL with timestamp copied to clipboard. - Shorts - Shorts player - Back button in the toolbar cannot be hidden. - Shorts toolbar - Known issue: Title disappears when clicked. - Show fullscreen title - Skipped preloaded buffer. - "Skip preloaded buffer at video start to bypass default video quality enforcement delay. - -• When the video starts, there is a delay of approximately 0.7 seconds, but the default video quality is applied immediately. -• Does not apply to HDR videos, live stream videos, videos shorter than 10 seconds." - Skip preloaded buffer - Toast is not shown. - Toast is shown. - Show a toast when skipped + Enable phone layout + Tricks the dpi to use some phone layouts. + Enable tablet layout + Tricks the dpi to use some tablet layouts. + Spoof app version "Spoofing the client version to the old version. • This will change the appearance of the app, but unknown side effects may occur. • If later turned off, the old UI may remain until clear the app data." + Edit spoof app version + Type the spoof app version target. + Spoof app version target 17.41.37 - Restore old playlist shelf 18.05.40 - Restore old comment input box 18.17.43 - Restore old player flyout panel 18.33.40 - Restore old shorts action bar 18.38.45 - Restore old default video quality behavior "18.48.39 - Disables 'views' and 'likes' from being updated in real time" - Spoof app version target - Type the spoof app version target. - Edit spoof app version - Spoof app version - Spoofs the device dimensions in order to unlock higher video qualities that may not be available on your device. - Spoof device dimensions - "Player parameter not spoofed for feed videos. -Known issue: Feed videos will play for less than 1 minute before encountering playback issues." - "Player parameter spoofed for feed videos. + + Account menu + Hide or show elements in account menu and You tab. -Known issue: Automatically played feed videos will show up in your watch history." - Spoof player parameter in feed - "Spoofs player parameters to prevent playback issues. + Hide account menu + "Hide elements of the account menu and You tab. +Some components may not be hidden." + Account menu filter + List of account menu names to filter separated by a new line. + Hide handle + Handle is hidden. + Handle is shown. -Known issues: -• Enhanced bitrate is not available. -• No seekbar thumbnails for paid videos. -• Offline downloads may not work. -• Video may not start from the last watched time." - Spoof player parameter - Swipe controls - "Swipe gestures are disabled in 'Lock screen' mode." - "Swipe gestures are enabled in 'Lock screen' mode." - "Swipe gestures in 'Lock screen' mode" - The amount of threshold for swipe to occur. - Swipe magnitude threshold - The visibility of swipe overlay background. - Swipe background visibility - The text size for swipe overlay. - Swipe overlay text size - The amount of milliseconds the overlay is visible. - Swipe overlay timeout + + Custom filter + Hide components using custom filters. + + + Enable custom filter + Custom filter is enabled. + Custom filter is disabled. + Custom filter + List of component path builder strings to filter separated by new line. + Invalid custom filter: %s. + + + Navigation buttons + Hide or show navigation bar section components. + + Enable narrow navigation buttons + Spacing between navigation buttons becomes narrower. + Spacing between navigation buttons does not become narrower. + Hide create button + Create button is hidden. + Create button is shown. + Hide home button + Home button is shown. + Home button is hidden. + Hide library button + Library button is hidden. + Library button is shown. + Hide navigation label + Navigation label is hidden. + Navigation label is shown. + Hide notifications button + Notifications button is hidden. + Notifications button is shown. + Hide shorts button + Shorts button is hidden. + Shorts button is shown. + Hide subscriptions button + Subscriptions button is hidden. + Subscriptions button is shown. + Switch create with notifications "Switch the positions of the create button and notification button by spoofing device information. • Even if you change this setting, it may not take effect until you reboot the device. • Disabling this setting loads more ads from the server side. • You should disable this setting to make video ads visible." - Switch create with notifications - Tool used - Video + + + Player + + Custom player overlay opacity + Opacity value between 0-100, where 0 is transparent. + Player overlay opacity must be between 0-100. Reset to default values. + Disable player popup panels + Auto player popup panels are enabled. + Auto player popup panels are disabled. + Disable speed overlay + "Disable 'Playing at 2x speed' while holding down. + +Note: Disabling the speed overlay restores the 'Slide to seek' behavior of the old layout." + Hide channel watermark + Channel watermark is hidden. + Channel watermark is shown. + Hide crowdfunding box + Crowdfunding box is hidden. + Crowdfunding box is shown. + Hide end screen cards + End screen cards are hidden. + End screen cards are shown. + Hide film strip overlay + Film strip overlay is hidden. + Film strip overlay is shown. + Hide info cards + Info cards are hidden. + Info cards are shown. + Hide info panels + Info panels are hidden. + Info panels are shown. + Hide medical panels + Medical panels are hidden. + Medical panels are shown. + Hide seek message + Seek message is hidden. + Seek message is shown. + Hide seek undo message + Seek undo message is hidden. + Seek undo message is shown. + Hide suggested actions + Suggested actions hidden. + Suggested actions shown. + Hide suggested video end screen + "This setting has been deprecated. + +Instead, use the 'Settings → Autoplay → Autoplay next video' setting." + Hide timed reactions + Timed reactions are hidden. + Timed reactions are shown. + + + Action buttons + Hide or show action buttons under videos. + + Hide clip button + Clip button is hidden. + Clip button is shown. + Hide download button + Download button is hidden. + Download button is shown. + Hide like and dislike buttons + Like and dislike buttons are hidden. + Like and dislike buttons are shown. + Hide remix button + Remix button is hidden. + Remix button is shown. + Hide report button + Report button is hidden. + Report button is shown. + Hide rewards button + Rewards button is hidden. + Rewards button is shown. + Hide save to playlist button + Save to playlist button is hidden. + Save to playlist button is shown. + Hide share button + Share button is hidden. + Share button is shown. + Hide shop button + Shop button is hidden. + Shop button is shown. + Hide thanks button + Thanks button is hidden. + Thanks button is shown. + + + Ambient mode + Bypass ambient mode restrictions or disable ambient mode. + + Bypass ambient mode restrictions + Ambient mode is enabled in battery saver mode. + Ambient mode is disabled in battery saver mode. + Disable ambient mode + Disables ambient mode. + Disable ambient mode in fullscreen + Disables ambient mode for fullscreen only. + + + Channel bar + Hide or show channel bar components under videos. + + Hide join button + Join button is hidden. + Join button is shown. + Hide start trial button + Start trial button is hidden. + Start trial button is shown. + + + Comments + Hide or show comments section components. + + Hide channel guidelines + Channel guidelines are hidden. + Channel guidelines are shown. + Hide comments by members banner + Comments by members banner is hidden. + Comments by members banner is shown. + Hide comments section + Comments section is hidden. + Comments section is shown. + Hide comments section in home feed + Comments section is hidden in home feed. + Comments section is shown in home feed. + Hide create shorts button + Create shorts button is hidden. + Create shorts button is shown. + Hide emoji picker and time stamp + Emoji picker and time stamp are hidden. + Emoji picker and time stamp are shown. + Hide preview comment + Preview comment is hidden. + Preview comment is shown. + Hide preview comment type + This does not change the size of the comment section, so it is possible to open the live chat replay in the comment section. + This changes the size of the comment section, so it is impossible to open a live chat replay in the comment section. + Hide thanks button + Thanks button is hidden. + Thanks button is shown. + + + Flyout menu + Hide or change flyout menu in the video player. + + Change toggle type + Text toggles are used. + Switch toggles are used. + Hide audio track menu + Audio track menu is hidden. + Audio track menu is shown. + Hide captions menu + Captions menu is hidden. + Captions menu is shown. + Hide captions menu footer + Captions menu footer is hidden. + Captions menu footer is shown. + Hide lock screen menu + Lock screen menu is hidden. + Lock screen menu is shown. + Hide more information menu + More information menu is hidden. + More information menu is shown. + Hide playback speed menu + Playback speed menu is hidden. + Playback speed menu is shown. + Hide quality menu footer + Quality menu footer is hidden. + Quality menu footer is shown. + Hide report menu + Report menu is hidden. + Report menu is shown. + + + Additional settings + Hide ambient mode menu + Ambient mode menu is hidden. + Ambient mode menu is shown. + Hide help & feedback menu + Help & feedback menu is hidden. + Help & feedback menu is shown. + Hide listen with YouTube Music menu + Listen with YouTube Music menu is hidden. + Listen with YouTube Music menu is shown. + Hide loop video menu + Loop video menu is hidden. + Loop video menu is shown. + Hide premium controls menu + Premium controls menu is hidden. + Premium controls menu is shown. + Stable volume menu is shown. + Stable volume menu is hidden. + Hide stable volume menu + Hide stats for nerds menu + Stats for nerds menu is hidden. + Stats for nerds menu is shown. + Hide watch in VR menu + Watch in VR menu is hidden. + Watch in VR menu is shown. + + + Fullscreen + Hide or change components related to fullscreen. + + Disable engagement panel + Engagement panel is disabled. + Engagement panel is enabled. + Show video title section + "Shows the video title section in full screen. + +Known issue: Video title disappears when clicked." + Autoplay preview container is hidden. + Autoplay preview container is shown. + Hide autoplay preview container + Related video overlay is hidden. + Related video overlay is shown. + Hide related video overlay + + + Quick actions + Hide quick actions container + Quick actions container is hidden. + Quick actions container is shown. + Hide comment button + Comment button is hidden. + Comment button is shown. + Hide dislike button + Dislike button is hidden. + Dislike button is shown. + Hide like button + Like button is hidden. + Like button is shown. + Hide live chat button + Live chat button is hidden. + Live chat button is shown. + Hide more button + More button is hidden. + More button is shown. + Hide open mix playlist button + Open mix playlist button is hidden. + Open mix playlist button is shown. + Hide open playlist button + Open playlist button is hidden. + Open playlist button is shown. + Hide related videos in quick actions + Related videos are hidden. + Related videos are shown. + Hide save to playlist button + Save to playlist button is hidden. + Save to playlist button is shown. + Hide share button + Share button is hidden. + Share button is shown. + Quick actions top margin + Configure the spacing from the seekbar to the quick action container, between 0-32. + Quick actions top margin must be between 0-32. Reset to default values. + + + Disable landscape mode + Video orientation is portrait mode in fullscreen. + Video orientation follows device settings in fullscreen. + Enable compact controls overlay + Controls overlay does not fill the fullscreen. + Controls overlay fills the fullscreen. + Force fullscreen + "Videos will be switched to fullscreen in the following situations: + +• When a timestamp in the comments is clicked on. +• When a video is started." + Keep landscape mode + Keeps landscape mode when turning the screen off and on in fullscreen. + Keep landscape mode timeout + The amount of milliseconds the landscape mode is forced. + + + Haptic feedback + Disable or enable haptic feedback. + + Disable chapters haptic feedback + Haptic feedback is disabled. + Haptic feedback is enabled. + Disable scrubbing haptic feedback + Haptic feedback is disabled. + Haptic feedback is enabled. + Disable seek haptic feedback + Haptic feedback is disabled. + Haptic feedback is enabled. + Disable seek undo haptic feedback + Haptic feedback is disabled. + Haptic feedback is enabled. + Disable zoom haptic feedback + Haptic feedback is disabled. + Haptic feedback is enabled. + + + Player buttons + Hide or show buttons in videos. + + Hide autoplay button + Autoplay button is hidden. + Autoplay button is shown. + Hide captions button + Captions button is hidden. + Captions button is shown. + Hide collapse button + Collapse button is hidden. + Collapse button is shown. + Hide fullscreen button + Fullscreen button is hidden. + Fullscreen button is shown. + Hide previous & next button + Buttons are hidden. + Buttons are shown. + Hide YouTube Music button + YouTube Music button is hidden. + YouTube Music button is shown. + + + Overlay buttons + Show always repeat button + Tap to toggle always repeat states. + Show copy video URL button + "Tap to copy video URL. +Tap and hold to copy video URL with timestamp." + Show copy timestamp URL button + "Tap to copy video URL with timestamp. +Tap and hold to copy video timestamp." + Show external download button + Tap to launch external downloader. + Show speed dialog button + "Tap to open speed dialog. +Tap and hold to set playback speed to 1.0x." + Playback speed reseted (1.0x). + External downloader package name + Package name of your installed external downloader app, such as NewPipe or YTDLnis. + External downloader + Warning + "%s is not installed. +Please download %s from the website." + %s is not installed. Please install it. + Override download action button + Download button opens your external downloader + Download button opens the native in-app downloader + + Time stamp copied to clipboard. (%s) + URL copied to clipboard. + URL with timestamp copied to clipboard. + + + Seekbar + Customize the seekbar components. + + Append time stamp information + Append time stamp information is enabled. + Append time stamp information is disabled. + Append information type + Append video quality. + Append playback speed. + Enable custom seekbar color + Custom seekbar color is enabled. + Custom seekbar color is disabled. + Custom seekbar color value + Type the hex code of the seekbar color. + Enable seekbar tapping + Seekbar tapping is enabled. + Seekbar tapping is disabled. + Hide seekbar in video player + Video player seekbar is hidden. + Video player seekbar is shown. + Hide seekbar in video thumbnails + Thumbnail seekbar is hidden. + Thumbnail seekbar is shown. + Hide time stamp + Time stamp is hidden. + Time stamp is shown. + Restore old seekbar thumbnails + Seekbar thumbnails will appear above the seekbar. + Seekbar thumbnails will appear in fullscreen. + + + Video description + Hide or show video description components. + + Hide chapters + Chapters are hidden. + Chapters are shown. + Hide game sections + Game sections are hidden. + Game sections are shown. + Hide info cards sections + Info cards sections are hidden. + Info cards sections are shown. + Hide music sections + Music sections are hidden. + Music sections are shown. + Hide place sections + Place sections are hidden. + Place sections are shown. + Hide podcast sections + Podcast sections are hidden. + Podcast sections are shown. + Hide shopping links + Shopping links are hidden. + Shopping links are shown. + Hide transcript sections + Transcript sections are hidden. + Transcript sections are shown. + + + Disable video description interaction + "Disables the following interactions when the video description is expanded: + +• Tap to scroll. +• Tap and hold to select text." + Expand video description + Video description is expanded automatically. + Video description is expanded manually. + + + + Shorts + + Change shorts repeat state + Autoplay + Default + Pause + Repeat + Disable resuming Shorts player + Shorts player will not resume on app startup + Shorts player will resume on app startup + Hide comments button + Comments button is hidden. + Comments button is shown. + Hide dislike button + Dislike button is hidden. + Dislike button is shown. + Hide info panels + Info panels are hidden. + Info panels are shown. + Hide join button + Join button is hidden. + Join button is shown. + Hide like button + Like button is hidden. + Like button is shown. + Hide paid promotion banner + Paid promotion banner is hidden. + Paid promotion banner is shown. + Hide remix button + Remix button is hidden. + Remix button is shown. + Hide share button + Share button is hidden. + Share button is shown. + Hide sound button + Sound button is hidden. + Sound button is shown. + Hide subscriptions button + Subscriptions button is hidden. + Subscriptions button is shown. + Hide thanks button + Thanks button is hidden. + Thanks button is shown. + Hide toolbar + Toolbar is hidden. + Toolbar is shown. + Hide navigation bar + Navigation bar is hidden. + Navigation bar is shown. + + + Shorts shelf + Hide or show shorts shelf in the feed, search, etc. + + Hide shorts shelf + "Hides Shorts shelves. + +Known issue: Official headers in search results will be hidden." + Show in watch history + Shorts shelves in watch history is shown. + Shorts shelves in watch history is hidden. + + + + Swipe controls + + Enable auto-brightness gesture + Lowest value of the brightness gesture activates auto-brightness. + Lowest value of the brightness gesture does not activate auto-brightness. + Enable brightness gesture + Brightness swipe is enabled. + Brightness swipe is disabled. + Enable volume gesture + Volume swipe is enabled. + Volume swipe is disabled. + Enable press-to-swipe gesture + Touch and hold to activate swipe gesture. + Touch to activate swipe gesture. + Enable haptic feedback + Haptic feedback is enabled. + Haptic feedback is disabled. + "Swipe gestures in 'Lock screen' mode" + "Swipe gestures are enabled in 'Lock screen' mode." + "Swipe gestures are disabled in 'Lock screen' mode." + Swipe background visibility + The visibility of swipe overlay background. + Swipe magnitude threshold + The amount of threshold for swipe to occur. + Swipe overlay text size + The text size for swipe overlay. + Swipe overlay timeout + The amount of milliseconds the overlay is visible. + Disable auto HDR brightness + Auto HDR brightness is disabled. + Auto HDR brightness is enabled. + Enable watch panel gestures + Entering fullscreen when swiping down below the video player is enabled. + Entering fullscreen when swiping down below the video player is disabled. + Auto + + + + Video + + Default playback speed + Default video quality on Mobile network + Default video quality on Wi-Fi network + Disable HDR video + HDR video is disabled. + HDR video is enabled. + Disable playback speed in live stream + Default playback speed is disabled in live stream. + Default playback speed is enabled in live stream. + Enable custom playback speed + Custom playback speed is enabled. + Custom playback speed is disabled. + Custom playback speed menu type + Custom dialog is used. + Old style flyout menu is used. + Edit custom playback speeds + Add or change available playback speeds. + Remember playback speed changes + Playback speed changes apply to all videos. + Playback speed changes only apply to the current video. + Remember video quality changes + Quality changes apply to all videos. + Quality changes only apply to the current video. + Restore old video quality menu + Old video quality menu is shown. + Old video quality menu is not shown. + Enable shorts default playback speed + Default playback speed applies to Shorts. + Default playback speed does not apply to Shorts. + Spoof device dimensions + Spoofs the device dimensions in order to unlock higher video qualities that may not be available on your device. + Skipped preloaded buffer. + Skip preloaded buffer + "Skip preloaded buffer at video start to bypass default video quality enforcement delay. + +• When the video starts, there is a delay of approximately 0.7 seconds, but the default video quality is applied immediately. +• Does not apply to HDR videos, live stream videos, videos shorter than 15 seconds." + Show a toast when skipped + Toast is shown. + Toast is not shown. + Changing default speed to %s. + Changing default mobile data quality to %s. + Failed to set video quality. + Changing default Wi-Fi quality to %s. + Invalid custom playback speeds. Reset to default values. + Custom speeds can\'t be more than %sx. Reset to default values. + + + + Return YouTube Dislike + + Enable Return YouTube Dislike + Dislikes are shown. + Dislikes are not shown. + Show dislikes on Shorts + Dislikes shown on Shorts. %s + Dislikes hidden on Shorts. + Limitation: Dislikes may not appear in certain situations. + Dislikes as percentage + Dislikes shown as percentage. + Dislikes shown as number. + Compact like button + Like button styled for minimum width. + Like button styled for best appearance. + + + About + ReturnYouTubeDislike.com + Dislike data is provided by the Return YouTube Dislike API. Tap here to learn more. + + Dislikes temporarily not available (API timed out). + Dislikes not available (status %d). + Dislikes not available (client API limit reached). + Dislikes not available (%s). + Show a toast if API is not available + Toast is not shown if Return YouTube Dislike is not available. + Toast is shown if Return YouTube Dislike is not available. + Hidden + + + + SponsorBlock Enable SponsorBlock SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos. + Appearance Show voting button Segment voting button is shown. @@ -904,50 +1016,7 @@ Known issues: Video length minus all segments, shown in parentheses next to the full video length. Full video length shown. - Creating new segments - Show create new segment button - Create new segment button is shown. - Create new segment button is not shown. - - Adjust new segment step - Number of milliseconds the time adjustment buttons move when creating new segments. - Value must be a positive number. - View guidelines - Guidelines contain rules and tips for creating new segments. - Follow the guidelines - Read the SponsorBlock guidelines before creating new segments. - Already read - Show me - - General - Show a toast if API is not available - Toast is shown if SponsorBlock is not available. - Toast is not shown if SponsorBlock is not available. - - Enable skip count tracking - Lets the SponsorBlock leaderboard know how much time is saved. A message is sent to the leaderboard each time a segment is skipped. - Skip count tracking is not enabled. - Minimum segment duration - Segments shorter than this value (in seconds) will not be shown or skipped. - Your private user id - This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you. - Private user id must be at least 30 characters long. - Change API URL - The address SponsorBlock uses to make calls to the server. Do not change this unless you know what you\'re doing. - API URL reset. - API URL is invalid. - API URL changed. - Copy - Import / Export settings - Your SponsorBlock JSON configuration that can be imported / exported to ReVanced Extended and other SponsorBlock platforms. %s - This includes your private user id. Be sure to share this wisely. - Settings imported successfully. - Failed to import: %s. - Failed to export: %s. - - Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n - Do not show again - + Change segment behavior Sponsor Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shout-outs to causes / creators / websites / products they like. @@ -1007,6 +1076,57 @@ Known issues: Show in seek bar Disable + Color: + Color changed. + Color reset. + Invalid color code. + Reset + Reset color + + + Creating new segments + Show create new segment button + Create new segment button is shown. + Create new segment button is not shown. + Adjust new segment step + Number of milliseconds the time adjustment buttons move when creating new segments. + Value must be a positive number. + View guidelines + Guidelines contain rules and tips for creating new segments. + Follow the guidelines + Read the SponsorBlock guidelines before creating new segments. + Already read + Show me + + + General + Show a toast if API is not available + Toast is shown if SponsorBlock is not available. + Toast is not shown if SponsorBlock is not available. + Enable skip count tracking + Lets the SponsorBlock leaderboard know how much time is saved. A message is sent to the leaderboard each time a segment is skipped. + Skip count tracking is not enabled. + Minimum segment duration + Segments shorter than this value (in seconds) will not be shown or skipped. + Your private user id + This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you. + Private user id must be at least 30 characters long. + Change API URL + The address SponsorBlock uses to make calls to the server. Do not change this unless you know what you\'re doing. + API URL reset. + API URL is invalid. + API URL changed. + Copy + Import / Export settings + Your SponsorBlock JSON configuration that can be imported / exported to ReVanced Extended and other SponsorBlock platforms. %s + This includes your private user id. Be sure to share this wisely. + Settings imported successfully. + Failed to import: %s. + Failed to export: %s. + + Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n + Do not show again + SponsorBlock temporarily not available. SponsorBlock temporarily not available (status %d). SponsorBlock temporarily not available (API timed out). @@ -1045,6 +1165,7 @@ Known issues: Do you want to edit the timing for the start or end of the segment? Invalid time given. + Stats Stats temporarily not available (API is down). Loading... @@ -1066,13 +1187,101 @@ Known issues: %s minutes %s seconds %s seconds - Color: - Color changed. - Color reset. - Invalid color code. - Reset color - - Reset + About + sponsor.ajay.app Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms. + + + + Miscellaneous + + Enable debug logging + Debug logs are enabled. + Debug logs are disabled. + Enable debug buffer logging + Debug logs include buffer. + Debug logs do not include buffer. + Enable external browser + External browser is enabled. + External browser is disabled. + Enable open links directly + Bypassing URL redirects. + Following default redirect policy. + Open default app settings + To open RVX in an external browser, turn on \'Open supported links\' and enable supported web addresses. + + Open GmsCore + Enable cloud messaging to receive notifications. + GmsCore does not have permission to run in the background. + GmsCore is not whitelisted from battery optimization. + Action needed + GmsCore is not installed. Install it. + "Follow the 'Don't kill my app' guide for GmsCore." + + Sanitize sharing links + Removes tracking query parameters from the URLs when sharing links. + Disable QUIC protocol + "Disable CronetEngine's QUIC protocol." + Spoof player parameter + "Spoofs player parameters to prevent playback issues. + +Known issues: +• Enhanced bitrate is not available. +• No seekbar thumbnails for paid videos. +• Offline downloads may not work. +• Video may not start from the last watched time." + Spoof player parameter in feed + "Player parameter spoofed for feed videos. + +Known issue: Automatically played feed videos will show up in your watch history." + "Player parameter not spoofed for feed videos. + +Known issue: Feed videos will play for less than 1 minute before encountering playback issues." + + + Import / Export settings + Import or export settings. + + + Import / Export as file + Export settings + Export settings to file. + Import settings + Import settings from saved file. + + + Import / Export as text + Import / Export as text + Import or export settings as text. + + Failed to export settings. + Settings were successfully exported. + Import + Copy + Failed to import settings. + Settings reset to default. + Settings were successfully imported. + Reset + Settings copied to clipboard. + + + Patch information + Information about applied patches. + + + Tool used + + + Others + Stock + Custom + Stock + MMT + Revancify Blue + Revancify Red + Stock + Excluded + Included + Stock \ No newline at end of file diff --git a/src/main/resources/youtube/settings/values-v21/strings.xml b/src/main/resources/youtube/settings/values-v21/strings.xml deleted file mode 100644 index a98e1e47a..000000000 --- a/src/main/resources/youtube/settings/values-v21/strings.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - <b>%1$s</b><br><br>This will change the language used on YouTube, including buttons, text and dialogs, but will not change the language of ReVanced Extended settings. - This will change the language used in the app including buttons, text and dialogs, but will not change the language of ReVanced Extended settings. - System default - - DeArrow - - ReVanced Extended - - @string/revanced_custom_filter_strings_summary - @string/revanced_custom_filter_strings_summary - - @string/revanced_hide_button_dislike_summary_off - @string/revanced_hide_button_dislike_summary_on - @string/revanced_hide_button_dislike_title - @string/revanced_hide_button_like_summary_off - @string/revanced_hide_button_like_summary_on - @string/revanced_hide_button_like_title - @string/revanced_hide_button_live_chat_summary_off - @string/revanced_hide_button_live_chat_summary_on - @string/revanced_hide_button_live_chat_title - @string/revanced_hide_button_open_mix_playlist_summary_off - @string/revanced_hide_button_open_mix_playlist_summary_on - @string/revanced_hide_button_open_mix_playlist_title - @string/revanced_hide_button_open_playlist_summary_off - @string/revanced_hide_button_open_playlist_summary_on - @string/revanced_hide_button_open_playlist_title - @string/revanced_hide_button_save_to_playlist_summary_off - @string/revanced_hide_button_save_to_playlist_summary_on - @string/revanced_hide_button_save_to_playlist_title - @string/revanced_hide_button_share_summary_off - @string/revanced_hide_button_share_summary_on - @string/revanced_hide_button_share_title - - - @string/revanced_hide_button_dislike_summary_off - @string/revanced_hide_button_dislike_summary_on - @string/revanced_hide_button_dislike_title - @string/revanced_hide_info_panel_summary_off - @string/revanced_hide_info_panel_summary_on - @string/revanced_hide_info_panel_title - @string/revanced_hide_join_button_summary_off - @string/revanced_hide_join_button_summary_on - @string/revanced_hide_join_button_title - @string/revanced_hide_button_like_summary_off - @string/revanced_hide_button_like_summary_on - @string/revanced_hide_button_like_title - @string/revanced_hide_paid_promotion_banner_summary_off - @string/revanced_hide_paid_promotion_banner_summary_on - @string/revanced_hide_paid_promotion_banner_title - @string/revanced_hide_button_remix_summary_off - @string/revanced_hide_button_remix_summary_on - @string/revanced_hide_button_remix_title - @string/revanced_hide_button_share_summary_off - @string/revanced_hide_button_share_summary_on - @string/revanced_hide_button_share_title - @string/revanced_hide_button_thanks_summary_off - @string/revanced_hide_button_thanks_summary_on - @string/revanced_hide_button_thanks_title - - Stock - Custom - Stock - MMT - Revancify Blue - Revancify Red - Stock - Excluded - Included - @string/shorts_speed_control_normal_label - - ReturnYouTubeDislike.com - - Return YouTube Dislike - - SponsorBlock - - Stock - - sponsor.ajay.app - diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index ab550493c..c1d292695 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -2,205 +2,145 @@ - - - - - - - - - - - + + + PREFERENCE_SCREEN: ADS --> - + + + + + + + PREFERENCE_SCREEN: ALTERNATIVE_THUMBNAILS --> - + - + - + - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + SETTINGS: CHANGE_START_PAGE --> + + - - @@ -208,132 +148,321 @@ SETTINGS: ENABLE_WIDE_SEARCH_BAR --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SETTINGS: PLAYER_COMPONENTS --> - - - - - - - - - - - + - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + - - + + - + - - - - - - - - - - - - - - - - - - - + + + + + - - - + + + - - + + + - - - - + + + + - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + - - - - + + + - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/shorts/host/values/arrays.xml b/src/main/resources/youtube/shorts/host/values/arrays.xml deleted file mode 100644 index 5daf00615..000000000 --- a/src/main/resources/youtube/shorts/host/values/arrays.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - @string/revanced_change_shorts_repeat_state_entry_default - @string/revanced_change_shorts_repeat_state_entry_repeat - @string/revanced_change_shorts_repeat_state_entry_auto_play - @string/revanced_change_shorts_repeat_state_entry_pause - - - 0 - 1 - 2 - 3 - - diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__0.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__0.xml deleted file mode 100644 index 35eb1ac38..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__0.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__1.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__1.xml deleted file mode 100644 index 35eb1ac38..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__1__1.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__0.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__0.xml deleted file mode 100644 index d6566bd9f..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__0.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__1.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__1.xml deleted file mode 100644 index d6566bd9f..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__2__1.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__0.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__0.xml deleted file mode 100644 index d6566bd9f..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__0.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__1.xml b/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__1.xml deleted file mode 100644 index d6566bd9f..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$$avd_anim__3__1.xml +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__0.xml b/src/main/resources/youtube/splashscreen/drawable/$avd_anim__0.xml deleted file mode 100644 index 4d4459196..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__0.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__1.xml b/src/main/resources/youtube/splashscreen/drawable/$avd_anim__1.xml deleted file mode 100644 index 6e99759e1..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__1.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__2.xml b/src/main/resources/youtube/splashscreen/drawable/$avd_anim__2.xml deleted file mode 100644 index 15d9885e9..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__2.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__3.xml b/src/main/resources/youtube/splashscreen/drawable/$avd_anim__3.xml deleted file mode 100644 index 8d6ff8a2e..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__3.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__4.xml b/src/main/resources/youtube/splashscreen/drawable/$avd_anim__4.xml deleted file mode 100644 index d4e222862..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/$avd_anim__4.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/drawable/avd_anim.xml b/src/main/resources/youtube/splashscreen/drawable/avd_anim.xml deleted file mode 100644 index 49266b4f4..000000000 --- a/src/main/resources/youtube/splashscreen/drawable/avd_anim.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/main/resources/youtube/splashscreen/values-v31/styles.xml b/src/main/resources/youtube/splashscreen/values-v31/styles.xml deleted file mode 100644 index c7462f74a..000000000 --- a/src/main/resources/youtube/splashscreen/values-v31/styles.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/src/main/resources/youtube/spoofappversion/host/values/arrays.xml b/src/main/resources/youtube/spoofappversion/host/values/arrays.xml deleted file mode 100644 index 40f0be50f..000000000 --- a/src/main/resources/youtube/spoofappversion/host/values/arrays.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - @string/revanced_spoof_app_version_target_entry_18_17_43 - @string/revanced_spoof_app_version_target_entry_18_05_40 - @string/revanced_spoof_app_version_target_entry_17_41_37 - - - 18.17.43 - 18.05.40 - 17.41.37 - - diff --git a/src/main/resources/youtube/startpage/host/values/arrays.xml b/src/main/resources/youtube/startpage/host/values/arrays.xml deleted file mode 100644 index bc663ac6b..000000000 --- a/src/main/resources/youtube/startpage/host/values/arrays.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - @string/revanced_change_start_page_entry_default - @string/revanced_change_start_page_entry_search - @string/revanced_change_start_page_entry_subscriptions - @string/revanced_change_start_page_entry_explore - @string/revanced_change_start_page_entry_shorts - @string/revanced_change_start_page_entry_library - @string/revanced_change_start_page_entry_liked_videos - @string/revanced_change_start_page_entry_history - @string/revanced_change_start_page_entry_trending - - - - - open.search - open.subscriptions - open.explore - open.shorts - - www.youtube.com/feed/library - www.youtube.com/playlist?list=LL - www.youtube.com/feed/history - www.youtube.com/feed/trending - -