From f51739a4fe8231406a4a04b04e3ae0cb15bdd7e7 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 5 Apr 2024 02:37:58 +0900 Subject: [PATCH] fix(YouTube/Fix suggested video end screen): no longer closes the `suggested video end screen`, but instead follows the autoplay settings --- .../SuggestedVideoEndScreenPatch.kt | 81 ++++++++++++++++ ...RemoveOnLayoutChangeListenerFingerprint.kt | 22 +++++ .../SuggestedVideoOverlayPatch.kt | 95 ------------------- .../CoreContainerBuilderFingerprint.kt | 19 ---- .../MiniPlayerPlayButtonFingerprint.kt | 11 --- .../TouchAreaOnClickListenerFingerprint.kt | 12 --- .../utils/resourceid/SharedResourceIdPatch.kt | 4 - .../youtube/settings/host/values/strings.xml | 8 +- .../youtube/settings/xml/revanced_prefs.xml | 7 +- 9 files changed, 110 insertions(+), 149 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/SuggestedVideoOverlayPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/CoreContainerBuilderFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/MiniPlayerPlayButtonFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/TouchAreaOnClickListenerFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt new file mode 100644 index 000000000..ed8b62278 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt @@ -0,0 +1,81 @@ +package app.revanced.patches.youtube.player.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.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.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) +) { + override fun execute(context: BytecodeContext) { + + /** + * The reasons why this patch is classified as a patch that fixes a 'bug' are as follows: + * 1. In YouTube v18.29.38, the suggested video end screen was only shown when the autoplay setting was turned on. + * 2. Starting from YouTube v18.35.36, the suggested video end screen is shown regardless of whether autoplay setting was turned on or off. + * + * This patch changes the suggested video end screen to be shown only when the autoplay setting is turned on. + * Automatically closing the suggested video end screen is not appropriate as it will disable the autoplay behavior. + */ + RemoveOnLayoutChangeListenerFingerprint.resultOrThrow().let { + val walkerIndex = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex) + + walkerIndex.apply { + val invokeInterfaceIndex = getTargetIndex(Opcode.INVOKE_INTERFACE) + val iGetObjectIndex = getTargetIndexReversed(invokeInterfaceIndex, Opcode.IGET_OBJECT) + + val invokeInterfaceReference = getInstruction(invokeInterfaceIndex).reference + val iGetObjectReference = getInstruction(iGetObjectIndex).reference + + addInstructionsWithLabels( + 0, + """ + iget-object v0, p0, $iGetObjectReference + + # This reference checks whether autoplay is turned on. + invoke-interface {v0}, $invokeInterfaceReference + move-result v0 + + # Hide suggested video end screen only when autoplay is turned off. + if-nez v0, :show_suggested_video_end_screen + return-void + """, + ExternalLabel( + "show_suggested_video_end_screen", + getInstruction(0) + ) + ) + } + } + + /** + * 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/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt new file mode 100644 index 000000000..3eeb8c165 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideoendscreen/fingerprints/RemoveOnLayoutChangeListenerFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.player.suggestedvideoendscreen.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.util.fingerprint.ReferenceFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +/** + * This fingerprint is also compatible with very old YouTube versions. + * Tested on YouTube v16.40.36, v18.29.38, v19.12.41. + */ +internal object RemoveOnLayoutChangeListenerFingerprint : ReferenceFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf( + Opcode.IPUT, + Opcode.INVOKE_VIRTUAL + ), + // This is the only reference present in the entire smali. + reference = { "YouTubePlayerOverlaysLayout;->removeOnLayoutChangeListener(Landroid/view/View${'$'}OnLayoutChangeListener;)V" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/SuggestedVideoOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/SuggestedVideoOverlayPatch.kt deleted file mode 100644 index 4fe1ab0b1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/SuggestedVideoOverlayPatch.kt +++ /dev/null @@ -1,95 +0,0 @@ -package app.revanced.patches.youtube.player.suggestedvideooverlay - -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.youtube.player.suggestedvideooverlay.fingerprints.CoreContainerBuilderFingerprint -import app.revanced.patches.youtube.player.suggestedvideooverlay.fingerprints.MiniPlayerPlayButtonFingerprint -import app.revanced.patches.youtube.player.suggestedvideooverlay.fingerprints.TouchAreaOnClickListenerFingerprint -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.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object SuggestedVideoOverlayPatch : BaseBytecodePatch( - name = "Hide suggested video overlay", - description = "Adds an option to hide the suggested video overlay at the end of videos.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - CoreContainerBuilderFingerprint, - TouchAreaOnClickListenerFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - CoreContainerBuilderFingerprint.resultOrThrow().let { parentResult -> - parentResult.mutableMethod.apply { - val addOnClickEventListenerIndex = parentResult.scanResult.patternScanResult!!.endIndex - 1 - val viewRegister = getInstruction(addOnClickEventListenerIndex).registerC - - addInstruction( - addOnClickEventListenerIndex + 1, - "invoke-static {v$viewRegister}, $PLAYER_CLASS_DESCRIPTOR->hideSuggestedVideoOverlay(Landroid/widget/ImageView;)V" - ) - } - - // Resolves fingerprints - MiniPlayerPlayButtonFingerprint.resolve(context, parentResult.classDef) - - MiniPlayerPlayButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSuggestedVideoOverlay()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - } - } - - TouchAreaOnClickListenerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertMethod = it.mutableClass.methods.find { method -> method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;") } - - insertMethod?.apply { - val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener") - val setOnClickListenerRegister = getInstruction(setOnClickListenerIndex).registerC - - addInstruction( - setOnClickListenerIndex + 1, - "invoke-static {v$setOnClickListenerRegister}, $PLAYER_CLASS_DESCRIPTOR->hideSuggestedVideoOverlayAutoPlay(Landroid/view/View;)V" - ) - } ?: throw PatchException("Failed to find setOnClickListener method") - } - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE: PLAYER_SETTINGS", - "SETTINGS: PLAYER_EXPERIMENTAL_FLAGS", - "SETTINGS: HIDE_SUGGESTED_VIDEO_OVERLAY" - ) - ) - - SettingsPatch.updatePatchStatus("Hide suggested video overlay") - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/CoreContainerBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/CoreContainerBuilderFingerprint.kt deleted file mode 100644 index afacc7d81..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/CoreContainerBuilderFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.player.suggestedvideooverlay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CoreContainer -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object CoreContainerBuilderFingerprint : LiteralValueFingerprint( - returnType = "Landroid/view/View;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Landroid/content/Context;"), - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST - ), - literalSupplier = { CoreContainer } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/MiniPlayerPlayButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/MiniPlayerPlayButtonFingerprint.kt deleted file mode 100644 index 0cb484445..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/MiniPlayerPlayButtonFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.player.suggestedvideooverlay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object MiniPlayerPlayButtonFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Landroid/content/Context;", "Landroid/view/View;") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/TouchAreaOnClickListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/TouchAreaOnClickListenerFingerprint.kt deleted file mode 100644 index 2e383bbc5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/player/suggestedvideooverlay/fingerprints/TouchAreaOnClickListenerFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.player.suggestedvideooverlay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TouchArea -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object TouchAreaOnClickListenerFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - literalSupplier = { TouchArea } -) \ No newline at end of file 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 659c5897c..a9a87c376 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 @@ -32,7 +32,6 @@ object SharedResourceIdPatch : ResourcePatch() { var CompactLink = -1L var CompactListItem = -1L var ControlsLayoutStub = -1L - var CoreContainer = -1L var DarkSplashAnimation = -1L var DonationCompanion = -1L var EasySeekEduContainer = -1L @@ -84,7 +83,6 @@ object SharedResourceIdPatch : ResourcePatch() { var TabsBarTextTabView = -1L var ToolTipContentView = -1L var TotalTime = -1L - var TouchArea = -1L var VideoQualityBottomSheet = -1L var VideoZoomIndicatorLayout = -1L var YoutubeControlsOverlay = -1L @@ -108,7 +106,6 @@ object SharedResourceIdPatch : ResourcePatch() { CompactLink = getId(LAYOUT, "compact_link") CompactListItem = getId(LAYOUT, "compact_list_item") ControlsLayoutStub = getId(ID, "controls_layout_stub") - CoreContainer = getId(ID, "core_container") DarkSplashAnimation = getId(ID, "dark_splash_animation") DonationCompanion = getId(LAYOUT, "donation_companion") EasySeekEduContainer = getId(ID, "easy_seek_edu_container") @@ -162,7 +159,6 @@ object SharedResourceIdPatch : ResourcePatch() { TabsBarTextTabView = getId(ID, "tabs_bar_text_tab_view") ToolTipContentView = getId(LAYOUT, "tooltip_content_view") TotalTime = getId(STRING, "total_time") - TouchArea = getId(ID, "touch_area") VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title") VideoZoomIndicatorLayout = getId(ID, "video_zoom_indicator_layout") YoutubeControlsOverlay = getId(ID, "youtube_controls_overlay") diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index d19e4349d..ea3085eea 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -664,10 +664,10 @@ Known issue: Official headers in search results will be hidden." Suggested actions shown. Suggested actions hidden. Hide suggested actions - When you finished a video, another play automatically - Auto play the next video - Hides suggested video overlay to play next. - Hide suggested video overlay + "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 diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 950e560e0..6ac4ee139 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -479,6 +479,7 @@ + @@ -491,7 +492,6 @@ - @@ -626,9 +626,8 @@ - +