From 05904a2569cf9b82e3731692b93bc3a6bb005b03 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 30 Apr 2023 22:34:57 +0400 Subject: [PATCH] feat(youtube/hide-get-premium): hide get premium advertisements under video player (#2020) Co-authored-by: oSumAtrIX --- .../HideGetPremiumCompatibility.kt | 8 ++ .../fingerprints/GetPremiumViewFingerprint.kt | 17 ++++ .../HideGetPremiumVideoAdvertisementPatch.kt | 77 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt new file mode 100644 index 000000000..6f373efd5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.layout.hide.getpremium.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("com.google.android.youtube", arrayOf("18.15.40"))]) +@Target(AnnotationTarget.CLASS) +internal annotation class HideGetPremiumCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt new file mode 100644 index 000000000..29cca3d03 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.layout.hide.getpremium.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object GetPremiumViewFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.ADD_INT_2ADDR, + Opcode.ADD_INT_2ADDR, + Opcode.INVOKE_VIRTUAL, + Opcode.RETURN_VOID + ), + customFingerprint = { methodDef -> + methodDef.definingClass == "Lcom/google/android/apps/youtube/app/red/presenter/CompactYpcOfferModuleView;" + && methodDef.name == "onMeasure" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt new file mode 100644 index 000000000..7e3e7b036 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt @@ -0,0 +1,77 @@ +package app.revanced.patches.youtube.layout.hide.getpremium.bytecode.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.instruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.layout.hide.getpremium.annotations.HideGetPremiumCompatibility +import app.revanced.patches.youtube.layout.hide.getpremium.bytecode.fingerprints.GetPremiumViewFingerprint +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction + +@Patch +@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) +@Name("hide-get-premium") +@Description("Hides advertisement for YouTube Premium under the video player.") +@HideGetPremiumCompatibility +@Version("0.0.1") +class HideGetPremiumPatch : BytecodePatch( + listOf( + GetPremiumViewFingerprint, + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( + SwitchPreference( + "revanced_hide_get_premium", + StringResource("revanced_hide_get_premium_title", "Hide YouTube Premium advertisement"), + true, + StringResource("revanced_hide_get_premium_summary_on", "YouTube Premium advertisement are hidden"), + StringResource("revanced_hide_get_premium_summary_off", "YouTube Premium advertisement are shown") + ) + ) + + GetPremiumViewFingerprint.result?.let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val measuredWidthRegister = (instruction(startIndex) as TwoRegisterInstruction).registerA + val measuredHeightInstruction = instruction(startIndex + 1) as TwoRegisterInstruction + val measuredHeightRegister = measuredHeightInstruction.registerA + val tempRegister = measuredHeightInstruction.registerB + + addInstructions( + startIndex + 2, + """ + # Override the internal measurement of the layout with zero values. + invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideGetPremiumView()Z + move-result v$tempRegister + if-eqz v$tempRegister, :allow + const/4 v$measuredWidthRegister, 0x0 + const/4 v$measuredHeightRegister, 0x0 + :allow + nop + # Layout width/height is then passed to a protected class method. + """ + ) + } + } ?: return GetPremiumViewFingerprint.toErrorResult() + + return PatchResultSuccess() + } + + private companion object { + const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/HideGetPremiumPatch;" + } +}