diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt index d45160e228..3e814898f2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt @@ -10,15 +10,10 @@ import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint import app.revanced.patches.music.misc.settings.PreferenceScreen import app.revanced.patches.shared.layout.branding.baseCustomBrandingPatch -import app.revanced.patches.shared.misc.mapping.ResourceType -import app.revanced.patches.shared.misc.mapping.getResourceId - import app.revanced.patches.shared.misc.mapping.resourceMappingPatch - import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversed -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.reference.MethodReference diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt index 2f9e701c50..d0bf1a5b5a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt @@ -12,6 +12,8 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.video.information.videoEndMethod import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.util.addInstructionsAtControlFlowLabel +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import com.android.tools.smali.dexlib2.Opcode @Suppress("unused") internal val exitFullscreenPatch = bytecodePatch( @@ -49,9 +51,13 @@ internal val exitFullscreenPatch = bytecodePatch( ListPreference("revanced_exit_fullscreen") ) - videoEndMethod.addInstructionsAtControlFlowLabel( - 0, - "invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->endOfVideoReached()V", - ) + videoEndMethod.apply { + val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.RETURN_VOID) + + addInstructionsAtControlFlowLabel( + insertIndex, + "invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->endOfVideoReached()V", + ) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/Fingerprints.kt new file mode 100644 index 0000000000..3101e61dcb --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/Fingerprints.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.misc.loopvideo + +import app.revanced.patcher.fingerprint +import app.revanced.patcher.string +import com.android.tools.smali.dexlib2.AccessFlags + +internal val videoStartPlaybackFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + instructions( + string("play() called when the player wasn't loaded."), + string("play() blocked because Background Playability failed") + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt index f2edb91c44..5b6d7138b4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt @@ -7,8 +7,8 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.loopvideo.button.loopVideoButtonPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import app.revanced.patches.youtube.shared.loopVideoFingerprint -import app.revanced.patches.youtube.shared.loopVideoParentFingerprint +import app.revanced.patches.youtube.video.information.videoEndMethod +import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode @@ -22,7 +22,8 @@ val loopVideoPatch = bytecodePatch( dependsOn( sharedExtensionPatch, addResourcesPatch, - loopVideoButtonPatch + loopVideoButtonPatch, + videoInformationPatch ) compatibleWith( @@ -40,9 +41,10 @@ val loopVideoPatch = bytecodePatch( SwitchPreference("revanced_loop_video"), ) - loopVideoFingerprint.match(loopVideoParentFingerprint.originalClassDef).method.apply { - val playMethod = loopVideoParentFingerprint.method - val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.RETURN_VOID) + videoEndMethod.apply { + // Add call to start playback again, but must not allow exit fullscreen patch call + // to be reached if the video is looped. + val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_VIRTUAL) + 1 addInstructionsAtControlFlowLabel( insertIndex, @@ -50,7 +52,8 @@ val loopVideoPatch = bytecodePatch( invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->shouldLoopVideo()Z move-result v0 if-eqz v0, :do_not_loop - invoke-virtual { p0 }, $playMethod + invoke-virtual { p0 }, ${videoStartPlaybackFingerprint.method} + return-void :do_not_loop nop """ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt index 4a66e83b7f..6ada54fb28 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt @@ -29,27 +29,6 @@ internal val conversionContextFingerprintToString = fingerprint { } } -/** - * Resolves to class found in [loopVideoParentFingerprint]. - */ -internal val loopVideoFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters() - custom { method, _ -> - method.implementation!!.instructions.count() == 3 && method.annotations.isEmpty() - } -} - -internal val loopVideoParentFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - instructions( - string("play() called when the player wasn't loaded."), - string("play() blocked because Background Playability failed") - ) -} - internal val layoutConstructorFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V")