diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/annotations/BreakingNewsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/annotations/BreakingNewsCompatibility.kt new file mode 100644 index 000000000..7baef62d5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/annotations/BreakingNewsCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.homepage.breakingnews.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.49.37") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class BreakingNewsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt new file mode 100644 index 000000000..d88c6a4e0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.youtube.layout.homepage.breakingnews.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.homepage.breakingnews.resource.patch.BreakingNewsResourcePatch +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction + +object BreakingNewsFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.CONST, + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IPUT_OBJECT, + ), + customFingerprint = { methodDef -> + methodDef.implementation?.instructions?.any { instruction -> + instruction.opcode.ordinal == Opcode.CONST.ordinal && + (instruction as? WideLiteralInstruction)?.wideLiteral == BreakingNewsResourcePatch.horizontalCardListId + } == true + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/patch/BreakingNewsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/patch/BreakingNewsPatch.kt new file mode 100644 index 000000000..91c94ddf2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/bytecode/patch/BreakingNewsPatch.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.youtube.layout.homepage.breakingnews.bytecode.patch + +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.addInstruction +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.youtube.layout.homepage.breakingnews.annotations.BreakingNewsCompatibility +import app.revanced.patches.youtube.layout.homepage.breakingnews.bytecode.fingerprints.BreakingNewsFingerprint +import app.revanced.patches.youtube.layout.homepage.breakingnews.resource.patch.BreakingNewsResourcePatch +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch +@DependsOn([IntegrationsPatch::class, BreakingNewsResourcePatch::class]) +@Name("hide-breaking-news-shelf") +@Description("Hides the breaking news shelf on the homepage tab.") +@BreakingNewsCompatibility +@Version("0.0.1") +class BreakingNewsPatch : BytecodePatch( + listOf( + BreakingNewsFingerprint, + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + val breakingNewsResult = BreakingNewsFingerprint.result!! + val breakingNewsMethod = breakingNewsResult.mutableMethod + + val moveResultObjectIndex = + breakingNewsResult.scanResult.patternScanResult!!.endIndex - 2 + + breakingNewsMethod.addInstruction( + moveResultObjectIndex + 1, """ + invoke-static {v${(breakingNewsMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideBreakingNewsPatch;->hideBreakingNews(Landroid/view/View;)V + """ + ) + + return PatchResultSuccess() + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/resource/patch/BreakingNewsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/resource/patch/BreakingNewsResourcePatch.kt new file mode 100644 index 000000000..2de1445a4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/homepage/breakingnews/resource/patch/BreakingNewsResourcePatch.kt @@ -0,0 +1,40 @@ +package app.revanced.patches.youtube.layout.homepage.breakingnews.resource.patch + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference + +@Name("breaking-news-shelf-resource-patch") +@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) +@Version("0.0.1") +class BreakingNewsResourcePatch : ResourcePatch { + companion object { + internal var horizontalCardListId: Long = -1 + } + + override fun execute(context: ResourceContext): PatchResult { + SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( + SwitchPreference( + "revanced_hide_breaking_news", + StringResource("revanced_hide_breaking_news_title", "Hide breaking news"), + true, + StringResource("revanced_hide_breaking_news_summary_on", "Breaking news are hidden"), + StringResource("revanced_hide_breaking_news_summary_off", "Breaking news are shown") + ) + ) + + horizontalCardListId = ResourceMappingPatch.resourceMappings.single { + it.type == "layout" && it.name == "horizontal_card_list" + }.id + + return PatchResultSuccess() + } +} \ No newline at end of file