From 315931cbf8f61cd4b3a54ace1ff03685d748614c Mon Sep 17 00:00:00 2001 From: trespyian Date: Tue, 23 Dec 2025 00:49:19 +1100 Subject: [PATCH] feat(SBS On Demand): Add `Remove ads` patch (#6378) Co-authored-by: Trespyian Co-authored-by: oSumAtrIX --- patches/api/patches.api | 4 ++ .../com/sbs/ondemand/tv/Fingerprints.kt | 28 ++++++++++++++ .../com/sbs/ondemand/tv/RemoveAdsPatch.kt | 37 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/RemoveAdsPatch.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index fdb8c1cf2..9f779cbed 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -176,6 +176,10 @@ public final class app/revanced/patches/cieid/restrictions/root/BypassRootChecks public static final fun getBypassRootChecksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/com/sbs/ondemand/tv/RemoveAdsPatchKt { + public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/cricbuzz/ads/DisableAdsPatchKt { public static final fun getDisableAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/Fingerprints.kt new file mode 100644 index 000000000..bf2ee4120 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/Fingerprints.kt @@ -0,0 +1,28 @@ +package app.revanced.patches.com.sbs.ondemand.tv + +import app.revanced.patcher.fingerprint + +internal val shouldShowAdvertisingTVFingerprint = fingerprint { + returns("Z") + custom { method, classDef -> + method.name == "getShouldShowAdvertisingTV" && + classDef.type == "Lcom/sbs/ondemand/common/InMemoryStorage;" + } +} + +internal val shouldShowPauseAdFingerprint = fingerprint { + returns("Z") + custom { method, classDef -> + method.name == "shouldShowPauseAd" && + classDef.type == "Lcom/sbs/ondemand/player/viewmodels/PauseAdController;" + } +} + +internal val requestAdStreamFingerprint = fingerprint { + returns("V") + custom { method, classDef -> + method.name == "requestAdStream\$player_googleStoreTvRelease" && + classDef.type == "Lcom/sbs/ondemand/player/viewmodels/AdsController;" + } +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/RemoveAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/RemoveAdsPatch.kt new file mode 100644 index 000000000..1b628562a --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/com/sbs/ondemand/tv/RemoveAdsPatch.kt @@ -0,0 +1,37 @@ +package app.revanced.patches.com.sbs.ondemand.tv + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.shared.misc.pairip.license.disableLicenseCheckPatch +import app.revanced.util.returnEarly + +@Suppress("unused") +val removeAdsPatch = bytecodePatch( + name = "Remove ads", + description = "Removes pre-roll, pause and on-demand advertisements from SBS On Demand TV.", +) { + compatibleWith("com.sbs.ondemand.tv") + + dependsOn(disableLicenseCheckPatch) + + execute { + shouldShowAdvertisingTVFingerprint.method.returnEarly(true) + shouldShowPauseAdFingerprint.method.returnEarly(false) + + // Remove on-demand pre-roll advertisements using exception handling. + // Exception handling is used instead of returnEarly() because: + // 1. returnEarly() causes black screen when the app waits for ad content that never comes. + // 2. SBS app has built-in exception handling in handleProviderFailure(). + // 3. Exception triggers fallbackToAkamaiProvider() which loads actual content. + // 4. This preserves the intended app flow: first try ads, then fail gracefully, then load content. + requestAdStreamFingerprint.method.addInstructions( + 0, + """ + new-instance v0, Ljava/lang/RuntimeException; + const-string v1, "Ad stream disabled" + invoke-direct {v0, v1}, Ljava/lang/RuntimeException;->(Ljava/lang/String;)V + throw v0 + """ + ) + } +}