From 3a8c8850fb8a35c4651da1bfe2f31624aaa0c6f9 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 1 Dec 2023 21:59:02 +0900 Subject: [PATCH] feat(YouTube/Hide suggestions shelf): add method to detect navbar index --- .../suggestions/SuggestionsShelfPatch.kt | 2 + .../fingerprints/OnBackPressedFingerprint.kt | 9 -- .../DoubleBackToClosePatch.kt | 2 +- .../fingerprint/OnBackPressedFingerprint.kt | 16 +++ .../utils/navbarindex/NavBarIndexHookPatch.kt | 130 ++++-------------- .../OnResumeFragmentsFingerprints.kt | 10 -- ...erprint.kt => PivotBarIndexFingerprint.kt} | 11 +- .../youtube/settings/host/values/strings.xml | 10 ++ .../youtube/settings/xml/revanced_prefs.xml | 3 +- 9 files changed, 67 insertions(+), 126 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/OnBackPressedFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/fingerprint/OnBackPressedFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/OnResumeFragmentsFingerprints.kt rename src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/{DefaultTabsBarFingerprint.kt => PivotBarIndexFingerprint.kt} (64%) diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/suggestions/SuggestionsShelfPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/suggestions/SuggestionsShelfPatch.kt index c7e9b461f..4e871e99c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/suggestions/SuggestionsShelfPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/suggestions/SuggestionsShelfPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.youtube.general.suggestions.fingerprints.BreakingNewsFingerprint import app.revanced.patches.youtube.utils.browseid.BrowseIdHookPatch import app.revanced.patches.youtube.utils.litho.LithoFilterPatch +import app.revanced.patches.youtube.utils.navbarindex.NavBarIndexHookPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.integrations.Constants.COMPONENTS_PATH import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -20,6 +21,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction dependencies = [ BrowseIdHookPatch::class, LithoFilterPatch::class, + NavBarIndexHookPatch::class, SettingsPatch::class ], compatiblePackages = [ diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/OnBackPressedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/OnBackPressedFingerprint.kt deleted file mode 100644 index fb4780a5e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/OnBackPressedFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.utils.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -object OnBackPressedFingerprint : MethodFingerprint( - opcodes = listOf(Opcode.RETURN_VOID), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/WatchWhileActivity;") && methodDef.name == "onBackPressed" } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/DoubleBackToClosePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/DoubleBackToClosePatch.kt index f2f7b3d07..5e1baed47 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/DoubleBackToClosePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/DoubleBackToClosePatch.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.utils.fingerprints.OnBackPressedFingerprint +import app.revanced.patches.youtube.utils.fix.doublebacktoclose.fingerprint.OnBackPressedFingerprint import app.revanced.patches.youtube.utils.fix.doublebacktoclose.fingerprint.ScrollPositionFingerprint import app.revanced.patches.youtube.utils.fix.doublebacktoclose.fingerprint.ScrollTopFingerprint import app.revanced.patches.youtube.utils.fix.doublebacktoclose.fingerprint.ScrollTopParentFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/fingerprint/OnBackPressedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/fingerprint/OnBackPressedFingerprint.kt new file mode 100644 index 000000000..f62d974c6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/doublebacktoclose/fingerprint/OnBackPressedFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.utils.fix.doublebacktoclose.fingerprint + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +object OnBackPressedFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf(Opcode.RETURN_VOID), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("WatchWhileActivity;") + && methodDef.name == "onBackPressed" + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/NavBarIndexHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/NavBarIndexHookPatch.kt index 929a62eaa..c1f5a01ac 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/NavBarIndexHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/NavBarIndexHookPatch.kt @@ -1,139 +1,69 @@ package app.revanced.patches.youtube.utils.navbarindex import app.revanced.extensions.exception -import app.revanced.extensions.findMutableMethodOf import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.utils.fingerprints.OnBackPressedFingerprint -import app.revanced.patches.youtube.utils.navbarindex.fingerprints.DefaultTabsBarFingerprint import app.revanced.patches.youtube.utils.navbarindex.fingerprints.MobileTopBarButtonOnClickFingerprint -import app.revanced.patches.youtube.utils.navbarindex.fingerprints.OnResumeFragmentsFingerprints +import app.revanced.patches.youtube.utils.navbarindex.fingerprints.PivotBarIndexFingerprint import app.revanced.patches.youtube.utils.navbarindex.fingerprints.SettingsActivityOnBackPressedFingerprint import app.revanced.util.integrations.Constants.UTILS_PATH -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.Reference @Suppress("unused") object NavBarIndexHookPatch : BytecodePatch( setOf( - DefaultTabsBarFingerprint, MobileTopBarButtonOnClickFingerprint, - OnBackPressedFingerprint, - OnResumeFragmentsFingerprints, + PivotBarIndexFingerprint, SettingsActivityOnBackPressedFingerprint ) ) { - override fun execute(context: BytecodeContext) { - - /** - * Change NavBar Index value according to selected Tab - */ - DefaultTabsBarFingerprint.result?.let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex - val setTabIndexReference = - getInstruction(targetIndex).reference - - val (onClickMethod, insertIndex) = getOnClickMethod(context, setTabIndexReference) - - onClickMethod.apply { - val indexRegister = - getInstruction(insertIndex).registerD - - addInstruction( - insertIndex, - "invoke-static {v$indexRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentNavBarIndex(I)V" - ) - } - } - } ?: throw DefaultTabsBarFingerprint.exception - - /** - * Set NavBar index to last index on back press - */ - mapOf( - OnBackPressedFingerprint to 0, - OnResumeFragmentsFingerprints to 1, - SettingsActivityOnBackPressedFingerprint to 0 - ).forEach { (fingerprint, index) -> - fingerprint.setLastNavBarIndexHook(index) - } - - /** - * Set Navbar index to zero on clicking MobileTopBarButton - * May be you want to switch to Incognito mode while in Library Tab - */ - MobileTopBarButtonOnClickFingerprint.result?.let { - it.mutableMethod.apply { - addInstructions( - 0, """ - const/4 v0, 0x0 - invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentNavBarIndex(I)V - """ - ) - } - } ?: throw MobileTopBarButtonOnClickFingerprint.exception - } - private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$UTILS_PATH/NavBarIndexPatch;" - private fun getOnClickMethod( - context: BytecodeContext, - targetReference: Reference - ): Pair { - context.classes.forEach { classDef -> - classDef.methods.forEach { method -> - if (method.name == "onClick") { - method.implementation?.instructions?.forEachIndexed { index, instruction -> - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) - return@forEachIndexed - if ((instruction as ReferenceInstruction).reference != targetReference) - return@forEachIndexed + override fun execute(context: BytecodeContext) { - val targetMethod = context.proxy(classDef) - .mutableClass - .findMutableMethodOf(method) - - return Pair(targetMethod, index) - } - } - } - } - throw PatchException("OnClickMethod not found!") - } - - /** - * Hook setLastNavBarIndex method - * - * @param insertIndex target index at which we want to inject the method call - */ - private fun MethodFingerprint.setLastNavBarIndexHook(insertIndex: Int) { - result?.let { + /** + * Change NavBar Index value according to selected Tab. + */ + PivotBarIndexFingerprint.result?.let { it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + 1 + val booleanRegister = getInstruction(insertIndex).registerD + val freeRegister = implementation!!.registerCount - parameters.size - 2 + addInstruction( insertIndex, - "invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->setLastNavBarIndex()V" + "invoke-static {v$freeRegister, v$booleanRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setNavBarIndex(IZ)V" + ) + addInstruction( + 0, + "move/16 v$freeRegister, p1" ) } - } ?: throw exception + } ?: throw PivotBarIndexFingerprint.exception + + /** + * Since it is used only after opening the library tab, set index to 4. + */ + arrayOf( + MobileTopBarButtonOnClickFingerprint, + SettingsActivityOnBackPressedFingerprint + ).forEach { fingerprint -> + fingerprint.injectIndex() + } } - internal fun MethodFingerprint.injectIndex(index: Int) { + private fun MethodFingerprint.injectIndex() { result?.let { it.mutableMethod.apply { addInstructions( 0, """ - const/4 v0, 0x$index - invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentNavBarIndex(I)V + const/4 v0, 0x4 + invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setNavBarIndex(I)V """ ) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/OnResumeFragmentsFingerprints.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/OnResumeFragmentsFingerprints.kt deleted file mode 100644 index b8f7e21b2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/OnResumeFragmentsFingerprints.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.utils.navbarindex.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -object OnResumeFragmentsFingerprints : MethodFingerprint( - customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("WatchWhileActivity;") - && methodDef.name == "onResumeFragments" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/DefaultTabsBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/PivotBarIndexFingerprint.kt similarity index 64% rename from src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/DefaultTabsBarFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/PivotBarIndexFingerprint.kt index 419310202..75e4a0326 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/DefaultTabsBarFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navbarindex/fingerprints/PivotBarIndexFingerprint.kt @@ -5,13 +5,14 @@ import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -object DefaultTabsBarFingerprint : MethodFingerprint( +object PivotBarIndexFingerprint : MethodFingerprint( returnType = "V", - accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, - parameters = listOf("Landroid/view/View;"), + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("I", "Z"), opcodes = listOf( + Opcode.IGET_OBJECT, Opcode.INVOKE_VIRTUAL, - Opcode.IGET + Opcode.INVOKE_VIRTUAL ), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/DefaultTabsBar;") } + customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/PivotBar;") } ) \ No newline at end of file diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index c33504b96..390241c85 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -589,6 +589,16 @@ Known issue: Official headers in search results are hidden." Known issue: Autoplay does not work." Hide suggested video overlay + "Identifies the suggestions shelf through the browse id. + +Known issues: +• When Browseid is not identified, suggestions shelf may not be hidden." + "Identifies the suggestions shelf through the current tab. + +Known issues: +• More drawer shelves may be hidden. +• Playlist shelves may be hidden." + Select method to hide shelves "Hides following shelves: • Breaking news • Continue watching diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 96b2dc55b..a36af0497 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -247,7 +247,8 @@ SETTINGS: GENERAL_EXPERIMENTAL_FLAGS --> + + SETTINGS: HIDE_SUGGESTIONS_SHELF -->