From a6e2c7d9187dc3e289b89899d40e2e06fec3e87d Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 26 Jul 2024 19:26:33 +0900 Subject: [PATCH] fix(YouTube/Disable auto captions): turning on `Disable forced auto captions` will disable subtitles https://github.com/inotia00/ReVanced_Extended/issues/2267 --- .../autocaptions/AutoCaptionsBytecodePatch.kt | 2 +- .../general/autocaptions/AutoCaptionsPatch.kt | 5 -- .../shared/captions/BaseAutoCaptionsPatch.kt | 63 ++++++++++--------- .../SubtitleButtonControllerFingerprint.kt | 23 +++++++ .../fingerprints/SubtitleTrackFingerprint.kt | 11 +--- .../autocaptions/AutoCaptionsBytecodePatch.kt | 2 +- .../general/autocaptions/AutoCaptionsPatch.kt | 9 +-- 7 files changed, 66 insertions(+), 49 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleButtonControllerFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsBytecodePatch.kt index 443fc43a5..8deda0978 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsBytecodePatch.kt @@ -3,4 +3,4 @@ package app.revanced.patches.music.general.autocaptions import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.shared.captions.BaseAutoCaptionsPatch -object AutoCaptionsBytecodePatch : BaseAutoCaptionsPatch(GENERAL_CLASS_DESCRIPTOR) \ No newline at end of file +object AutoCaptionsBytecodePatch : BaseAutoCaptionsPatch(GENERAL_CLASS_DESCRIPTOR, false) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt index f3efcaddc..c50428704 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt @@ -2,10 +2,8 @@ package app.revanced.patches.music.general.autocaptions import app.revanced.patcher.data.ResourceContext import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.video.videoid.VideoIdPatch import app.revanced.util.patch.BaseResourcePatch @Suppress("unused") @@ -15,14 +13,11 @@ object AutoCaptionsPatch : BaseResourcePatch( dependencies = setOf( AutoCaptionsBytecodePatch::class, SettingsPatch::class, - VideoIdPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE ) { override fun execute(context: ResourceContext) { - VideoIdPatch.hookVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - SettingsPatch.addSwitchPreference( CategoryType.GENERAL, "revanced_disable_auto_captions", diff --git a/src/main/kotlin/app/revanced/patches/shared/captions/BaseAutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/captions/BaseAutoCaptionsPatch.kt index 26502d3de..cd819bf5f 100644 --- a/src/main/kotlin/app/revanced/patches/shared/captions/BaseAutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/captions/BaseAutoCaptionsPatch.kt @@ -1,58 +1,65 @@ package app.revanced.patches.shared.captions import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.captions.fingerprints.SubtitleButtonControllerFingerprint import app.revanced.patches.shared.captions.fingerprints.SubtitleTrackFingerprint import app.revanced.patches.shared.fingerprints.StartVideoInformerFingerprint -import app.revanced.util.getWalkerMethod -import app.revanced.util.indexOfFirstInstruction 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.reference.MethodReference abstract class BaseAutoCaptionsPatch( - private val classDescriptor: String + private val classDescriptor: String, + private val captionsButtonStatus: Boolean ) : BytecodePatch( setOf( StartVideoInformerFingerprint, + SubtitleButtonControllerFingerprint, SubtitleTrackFingerprint ) ) { override fun execute(context: BytecodeContext) { - StartVideoInformerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstruction( - 0, - "invoke-static {}, $classDescriptor->prefetchSubtitleTrack()V" + SubtitleTrackFingerprint.resultOrThrow().mutableMethod.apply { + if (captionsButtonStatus) { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $classDescriptor->disableAutoCaptions()Z + move-result v0 + if-eqz v0, :disabled + const/4 v0, 0x1 + return v0 + """, ExternalLabel("disabled", getInstruction(0)) ) - } - } - - SubtitleTrackFingerprint.resultOrThrow().let { - val targetMethod = - it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1) - - targetMethod.apply { - val targetIndex = indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL - && ((this as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" - } + 1 - val insertRegister = getInstruction(targetIndex).registerA + } else { + val index = implementation!!.instructions.lastIndex + val register = getInstruction(index).registerA addInstructions( - targetIndex + 1, """ - invoke-static {v$insertRegister}, $classDescriptor->disableAutoCaptions(Z)Z - move-result v$insertRegister + index, """ + invoke-static {v$register}, $classDescriptor->disableAutoCaptions(Z)Z + move-result v$register """ ) } } + if (!captionsButtonStatus) return + + mapOf( + StartVideoInformerFingerprint to 0, + SubtitleButtonControllerFingerprint to 1 + ).forEach { (fingerprint, enabled) -> + fingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, """ + const/4 v0, 0x$enabled + invoke-static {v0}, $classDescriptor->setCaptionsButtonStatus(Z)V + """ + ) + } } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleButtonControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleButtonControllerFingerprint.kt new file mode 100644 index 000000000..4041509b5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleButtonControllerFingerprint.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.shared.captions.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 SubtitleButtonControllerFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;"), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.RETURN_VOID, + Opcode.IGET_BOOLEAN, + Opcode.CONST_4, + Opcode.IF_NEZ, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleTrackFingerprint.kt index 4d5f9a8b5..b1a6012a7 100644 --- a/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleTrackFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/captions/fingerprints/SubtitleTrackFingerprint.kt @@ -3,15 +3,10 @@ package app.revanced.patches.shared.captions.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 SubtitleTrackFingerprint : MethodFingerprint( - returnType = "V", + returnType = "Z", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ), - strings = listOf("subtitleTrack is null") + parameters = emptyList(), + strings = listOf("DISABLE_CAPTIONS_OPTION"), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsBytecodePatch.kt index ff4669673..914f4db85 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/autocaptions/AutoCaptionsBytecodePatch.kt @@ -3,4 +3,4 @@ package app.revanced.patches.youtube.general.autocaptions import app.revanced.patches.shared.captions.BaseAutoCaptionsPatch import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -object AutoCaptionsBytecodePatch : BaseAutoCaptionsPatch(GENERAL_CLASS_DESCRIPTOR) \ No newline at end of file +object AutoCaptionsBytecodePatch : BaseAutoCaptionsPatch(GENERAL_CLASS_DESCRIPTOR, true) \ 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 eecdfd12e..52a9b95a0 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 @@ -2,9 +2,8 @@ package app.revanced.patches.youtube.general.autocaptions import app.revanced.patcher.data.BytecodeContext import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.util.patch.BaseBytecodePatch @Suppress("unused") @@ -13,15 +12,13 @@ object AutoCaptionsPatch : BaseBytecodePatch( description = "Adds an option to disable captions from being automatically enabled.", dependencies = setOf( AutoCaptionsBytecodePatch::class, - SettingsPatch::class, - VideoInformationPatch::class + PlayerTypeHookPatch::class, + SettingsPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE ) { override fun execute(context: BytecodeContext) { - VideoInformationPatch.hook("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") - /** * Add settings */