From 198cb93ef275a09891ac59364225198b83524ab3 Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Mon, 12 Jan 2026 17:10:00 +0700 Subject: [PATCH] refactor(primevideo): SkipAdsPatch --- .../patches/primevideo/ads/Fingerprints.kt | 50 +++++++++++-------- .../patches/primevideo/ads/SkipAdsPatch.kt | 22 +++++--- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/Fingerprints.kt index ac3a1c43a5..25831a4bb1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/Fingerprints.kt @@ -1,33 +1,39 @@ package app.revanced.patches.primevideo.ads -import app.revanced.patcher.fingerprint +import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.accessFlags +import app.revanced.patcher.definingClass +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.name +import app.revanced.patcher.parameterTypes +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val enterServerInsertedAdBreakStateFingerprint = fingerprint { +internal val BytecodePatchContext.enterServerInsertedAdBreakStateMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC) - parameters("Lcom/amazon/avod/fsm/Trigger;") - returns("V") - opcodes( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.CONST_4 + parameterTypes("Lcom/amazon/avod/fsm/Trigger;") + returnType("V") + instructions( + Opcode.INVOKE_VIRTUAL(), + Opcode.MOVE_RESULT_OBJECT(), + Opcode.CONST_4(), + Opcode.CONST_4() ) - custom { method, classDef -> - method.name == "enter" && classDef.type == "Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;" - } + name("enter") + definingClass("Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;") } -internal val doTriggerFingerprint = fingerprint { +internal val BytecodePatchContext.doTriggerMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PROTECTED) - returns("V") - opcodes( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.RETURN_VOID + returnType("V") + instructions( + Opcode.IGET_OBJECT(), + Opcode.INVOKE_INTERFACE(), + Opcode.RETURN_VOID() ) - custom { method, classDef -> - method.name == "doTrigger" && classDef.type == "Lcom/amazon/avod/fsm/StateBase;" - } -} \ No newline at end of file + name("doTrigger") + definingClass("Lcom/amazon/avod/fsm/StateBase;") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/SkipAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/SkipAdsPatch.kt index d223490b6a..0168e77640 100644 --- a/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/SkipAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/primevideo/ads/SkipAdsPatch.kt @@ -2,14 +2,17 @@ package app.revanced.patches.primevideo.ads import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction -import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.primevideo.misc.extension.sharedExtensionPatch +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow 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.iface.reference.MethodReference -@Suppress("unused") -val skipAdsPatch = bytecodePatch( - name = "Skip ads", +@Suppress("unused", "ObjectPropertyName") +val `Skip ads` by creatingBytecodePatch( description = "Automatically skips video stream ads.", ) { compatibleWith("com.amazon.avod.thirdpartyclient"("3.0.412.2947")) @@ -20,13 +23,17 @@ val skipAdsPatch = bytecodePatch( // ad break. Instead, force the video player to seek over the entire break and reset the state machine. apply { // Force doTrigger() access to public so we can call it from our extension. - doTriggerFingerprint.method.accessFlags = AccessFlags.PUBLIC.value; + doTriggerMethod.accessFlags = AccessFlags.PUBLIC.value - val getPlayerIndex = enterServerInsertedAdBreakStateFingerprint.patternMatch.startIndex - enterServerInsertedAdBreakStateFingerprint.method.apply { + enterServerInsertedAdBreakStateMethod.apply { // Get register that stores VideoPlayer: // invoke-virtual ->getPrimaryPlayer() // move-result-object { playerRegister } + val getPlayerIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "getPrimaryPlayer" + } + val playerRegister = getInstruction(getPlayerIndex + 1).registerA // Reuse the params from the original method: @@ -42,4 +49,3 @@ val skipAdsPatch = bytecodePatch( } } } -