From e85a343c02295c3c6212d6e5c9ba4ccf1f83bd34 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 22 Jan 2025 12:52:50 +0900 Subject: [PATCH] fix(Reddit - Remove subreddit dialog): Navigation bar is not visible when `Remove notification suggestion dialog` setting is turned on (Reddit 2025.02+) --- .../patches/RemoveSubRedditDialogPatch.java | 17 ++--- .../layout/subredditdialog/Fingerprints.kt | 53 +++++++++------- .../subredditdialog/SubRedditDialogPatch.kt | 63 ++++++++++--------- .../reddit/utils/settings/SettingsPatch.kt | 3 + 4 files changed, 73 insertions(+), 63 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java b/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java index aaeb7468d..dc6672633 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/reddit/patches/RemoveSubRedditDialogPatch.java @@ -8,7 +8,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import app.revanced.extension.reddit.settings.Settings; -import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") @@ -31,20 +30,12 @@ public class RemoveSubRedditDialogPatch { clickViewDelayed(cancelButtonView); } - public static void dismissDialogV2(Object object) { - if (!Settings.REMOVE_NOTIFICATION_DIALOG.get()) - return; - - Utils.runOnMainThreadDelayed(() -> { - try { - dismissRedditDialogV2(object); - } catch (Exception ex) { - Logger.printException(() -> "dismissDialogV2 failed", ex); - } - }, 0); + public static boolean spoofHasBeenVisitedStatus(boolean hasBeenVisited) { + return Settings.REMOVE_NSFW_DIALOG.get() || hasBeenVisited; } - private static void dismissRedditDialogV2(Object object) { + public static boolean spoofLoggedInStatus(boolean isLoggedIn) { + return !Settings.REMOVE_NOTIFICATION_DIALOG.get() && isLoggedIn; } private static void clickViewDelayed(View view) { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt index f8ab5cc7b..cae1dc6d8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt @@ -3,11 +3,11 @@ package app.revanced.patches.reddit.layout.subredditdialog import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.indexOfFirstInstructionReversed import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val frequentUpdatesSheetScreenFingerprint = legacyFingerprint( @@ -26,38 +26,49 @@ internal val frequentUpdatesSheetScreenFingerprint = legacyFingerprint( } ) -internal val frequentUpdatesSheetV2ScreenFingerprint = legacyFingerprint( - name = "frequentUpdatesSheetV2ScreenFingerprint", - returnType = "V", +internal val frequentUpdatesHandlerFingerprint = legacyFingerprint( + name = "frequentUpdatesHandlerFingerprint", + returnType = "Ljava/lang/Object;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, strings = listOf("subreddit_name"), customFingerprint = { method, classDef -> - classDef.type == "Lcom/reddit/screens/pager/v2/FrequentUpdatesSheetV2Screen;" + classDef.type.startsWith("Lcom/reddit/screens/pager/FrequentUpdatesHandler${'$'}handleFrequentUpdates${'$'}") && + method.name == "invokeSuspend" && + listOfIsLoggedInInstruction(method).isNotEmpty() } ) -internal val frequentUpdatesSheetV2ScreenInvokeFingerprint = legacyFingerprint( - name = "frequentUpdatesSheetV2ScreenInvokeFingerprint", - returnType = "V", +fun listOfIsLoggedInInstruction(method: Method) = + method.implementation?.instructions + ?.withIndex() + ?.filter { (_, instruction) -> + val reference = (instruction as? ReferenceInstruction)?.reference + instruction.opcode == Opcode.INVOKE_INTERFACE && + reference is MethodReference && + reference.name == "isLoggedIn" && + reference.returnType == "Z" + } + ?.map { (index, _) -> index } + ?.reversed() + ?: emptyList() + +internal val nsfwAlertEmitFingerprint = legacyFingerprint( + name = "nsfwAlertEmitFingerprint", + returnType = "Ljava/lang/Object;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID, - ), - customFingerprint = { method, classDef -> - classDef.type.startsWith("Lcom/reddit/screens/pager/v2/FrequentUpdatesSheetV2Screen${'$'}SheetContent${'$'}") && - method.name == "invoke" && - indexOfDismissScreenInstruction(method) >= 0 + strings = listOf("reddit://reddit/r/", "nsfwAlertDelegate"), + customFingerprint = { method, _ -> + method.name == "emit" && + indexOfHasBeenVisitedInstruction(method) >= 0 } ) -fun indexOfDismissScreenInstruction(method: Method) = - method.indexOfFirstInstructionReversed { +fun indexOfHasBeenVisitedInstruction(method: Method) = + method.indexOfFirstInstruction { val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && - reference?.returnType == "V" && - reference.parameterTypes.isEmpty() + reference?.name == "getHasBeenVisited" && + reference.returnType == "Z" } internal val redditAlertDialogsFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt index b0dc35c86..25a3db115 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -8,10 +8,9 @@ import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACK import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.REMOVE_SUBREDDIT_DIALOG import app.revanced.patches.reddit.utils.settings.is_2024_41_or_greater +import app.revanced.patches.reddit.utils.settings.is_2025_01_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.addInstructionsAtControlFlowLabel -import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -19,7 +18,6 @@ import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = @@ -36,6 +34,25 @@ val subRedditDialogPatch = bytecodePatch( execute { + if (is_2024_41_or_greater) { + frequentUpdatesHandlerFingerprint + .methodOrThrow() + .apply { + listOfIsLoggedInInstruction(this) + .forEach { index -> + val register = getInstruction(index + 1).registerA + + addInstructions( + index + 2, """ + invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->spoofLoggedInStatus(Z)Z + move-result v$register + """ + ) + } + } + } + + // Not used in latest Reddit client. frequentUpdatesSheetScreenFingerprint.methodOrThrow().apply { val index = indexOfFirstInstructionReversedOrThrow(Opcode.RETURN_OBJECT) val register = @@ -43,39 +60,27 @@ val subRedditDialogPatch = bytecodePatch( addInstruction( index, - "invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->onDialogCreated(Landroid/view/View;)V" + "invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialog(Landroid/view/View;)V" ) } - if (is_2024_41_or_greater) { - val dismissReference = with (frequentUpdatesSheetV2ScreenInvokeFingerprint.methodOrThrow()) { - val index = indexOfDismissScreenInstruction(this) - getInstruction(index).reference as MethodReference + if (is_2025_01_or_greater) { + nsfwAlertEmitFingerprint.methodOrThrow().apply { + val hasBeenVisitedIndex = indexOfHasBeenVisitedInstruction(this) + val hasBeenVisitedRegister = + getInstruction(hasBeenVisitedIndex + 1).registerA + + addInstructions( + hasBeenVisitedIndex + 2, """ + invoke-static {v$hasBeenVisitedRegister}, $EXTENSION_CLASS_DESCRIPTOR->spoofHasBeenVisitedStatus(Z)Z + move-result v$hasBeenVisitedRegister + """ + ) } - - findMethodOrThrow(EXTENSION_CLASS_DESCRIPTOR) { - name == "dismissRedditDialogV2" - }.addInstructions( - 0, """ - check-cast p0, ${dismissReference.definingClass} - invoke-virtual {p0}, $dismissReference - """ - ) - - frequentUpdatesSheetV2ScreenFingerprint - .methodOrThrow() - .apply { - val targetIndex = indexOfFirstInstructionReversedOrThrow(Opcode.RETURN_VOID) - - addInstructionsAtControlFlowLabel( - targetIndex, - "invoke-static {p0}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialogV2(Ljava/lang/Object;)V" - ) - } } // Not used in latest Reddit client. - redditAlertDialogsFingerprint.second.methodOrNull?.apply { + redditAlertDialogsFingerprint.methodOrThrow().apply { val backgroundTintIndex = indexOfSetBackgroundTintListInstruction(this) val insertIndex = indexOfFirstInstructionOrThrow(backgroundTintIndex) { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt index 923817782..ae28725f9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt @@ -37,6 +37,8 @@ var is_2024_26_or_greater = false private set var is_2024_41_or_greater = false private set +var is_2025_01_or_greater = false + private set private val settingsBytecodePatch = bytecodePatch( description = "settingsBytecodePatch" @@ -59,6 +61,7 @@ private val settingsBytecodePatch = bytecodePatch( is_2024_26_or_greater = 2024260 <= versionNumber is_2024_41_or_greater = 2024410 <= versionNumber + is_2025_01_or_greater = 2025010 <= versionNumber } /**