diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt index dc02b6fc4..8496e2263 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/layout/LayoutComponentsPatch.kt @@ -21,13 +21,16 @@ object LayoutComponentsPatch : BaseBytecodePatch( "$COMPONENTS_PATH/ChannelBarFilter;" private const val CUSTOM_FILTER_CLASS_DESCRIPTOR = "$COMPONENTS_PATH/CustomFilter;" - private const val FILTER_CLASS_DESCRIPTOR = + private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR = "$COMPONENTS_PATH/LayoutComponentsFilter;" + private const val KEYWORD_FILTER_CLASS_NAME = + "$COMPONENTS_PATH/KeywordContentFilter;" override fun execute(context: BytecodeContext) { LithoFilterPatch.addFilter(CHANNEL_BAR_FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR) - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME) /** * Add settings diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt index 8f3e4423d..4ce769828 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/NavigationButtonsPatch.kt @@ -1,26 +1,16 @@ package app.revanced.patches.youtube.navigation.navigationbuttons 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.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.AutoMotiveFingerprint -import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.PivotBarButtonViewFingerprint -import app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints.PivotBarEnumFingerprint -import app.revanced.patches.youtube.utils.fingerprints.PivotBarCreateButtonViewFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ImageOnlyTab +import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getTargetIndex -import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.Opcode.MOVE_RESULT_OBJECT import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") @@ -29,60 +19,13 @@ object NavigationButtonsPatch : BaseBytecodePatch( description = "Adds options to hide and change navigation buttons (such as the Shorts button).", dependencies = setOf( SettingsPatch::class, - SharedResourceIdPatch::class + NavigationBarHookPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - AutoMotiveFingerprint, - PivotBarCreateButtonViewFingerprint - ) + fingerprints = setOf(AutoMotiveFingerprint) ) { override fun execute(context: BytecodeContext) { - PivotBarCreateButtonViewFingerprint.resultOrThrow().let { parentResult -> - - /** - * Home, Shorts, Subscriptions Button - */ - with( - arrayOf( - PivotBarEnumFingerprint, - PivotBarButtonViewFingerprint - ).onEach { - it.resolve( - context, - parentResult.mutableMethod, - parentResult.mutableClass - ) - }.map { - it.resultOrThrow().scanResult.patternScanResult!! - } - ) { - val enumScanResult = this[0] - val buttonViewResult = this[1] - - val enumHookInsertIndex = enumScanResult.startIndex + 2 - val buttonHookInsertIndex = buttonViewResult.endIndex - - mapOf( - BUTTON_HOOK to buttonHookInsertIndex, - ENUM_HOOK to enumHookInsertIndex - ).forEach { (hook, insertIndex) -> - parentResult.mutableMethod.injectHook(hook, insertIndex) - } - } - - /** - * Create Button - */ - parentResult.mutableMethod.apply { - val constIndex = getWideLiteralInstructionIndex(ImageOnlyTab) - val insertIndex = getTargetIndex(constIndex, Opcode.INVOKE_VIRTUAL) + 2 - injectHook(CREATE_BUTTON_HOOK, insertIndex) - } - - } - /** * Switch create button with notifications button */ @@ -93,13 +36,17 @@ object NavigationButtonsPatch : BaseBytecodePatch( addInstructions( insertIndex, """ - invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->switchCreateNotification(Z)Z + invoke-static {v$register}, $NAVIGATION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton(Z)Z move-result v$register """ ) } } + // Hook navigation button created, in order to hide them. + NavigationBarHookPatch.hookNavigationButtonCreated(NAVIGATION_CLASS_DESCRIPTOR) + + /** * Add settings */ @@ -113,40 +60,4 @@ object NavigationButtonsPatch : BaseBytecodePatch( SettingsPatch.updatePatchStatus("Hide navigation buttons") } - - private const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX" - - private const val ENUM_HOOK = - "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $NAVIGATION_CLASS_DESCRIPTOR" + - "->" + - "lastPivotTab:Ljava/lang/Enum;" - - private const val BUTTON_HOOK = - "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $NAVIGATION_CLASS_DESCRIPTOR" + - "->" + - "hideNavigationButton(Landroid/view/View;)V" - - private const val CREATE_BUTTON_HOOK = - "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $NAVIGATION_CLASS_DESCRIPTOR" + - "->" + - "hideCreateButton(Landroid/view/View;)V" - - /** - * Injects an instruction into insertIndex of the hook. - * @param hook The hook to insert. - * @param insertIndex The index to insert the instruction at. - * [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex]. - */ - private fun MutableMethod.injectHook(hook: String, insertIndex: Int) { - val injectTarget = this - - // Register to pass to the hook - val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction - val register = injectTarget.getInstruction(registerIndex).registerA - - injectTarget.addInstruction( - insertIndex, - hook.replace("REGISTER_INDEX", register.toString()), - ) - } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarButtonViewFingerprint.kt deleted file mode 100644 index 42fe2c704..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarButtonViewFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object PivotBarButtonViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, // target reference - null, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarEnumFingerprint.kt deleted file mode 100644 index ef11f90be..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/navigation/navigationbuttons/fingerprints/PivotBarEnumFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.navigation.navigationbuttons.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object PivotBarEnumFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, // target reference - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt index b4594a63b..14a2ea010 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsNavigationBarPatch.kt @@ -8,7 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patches.youtube.shorts.components.fingerprints.BottomNavigationBarFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.RenderBottomNavigationBarFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.SetPivotBarFingerprint -import app.revanced.patches.youtube.utils.fingerprints.PivotBarCreateButtonViewFingerprint +import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR import app.revanced.util.getTargetIndexWithMethodReferenceName import app.revanced.util.getWalkerMethod @@ -18,13 +18,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction object ShortsNavigationBarPatch : BytecodePatch( setOf( BottomNavigationBarFingerprint, - PivotBarCreateButtonViewFingerprint, + InitializeButtonsFingerprint, RenderBottomNavigationBarFingerprint ) ) { override fun execute(context: BytecodeContext) { - PivotBarCreateButtonViewFingerprint.resultOrThrow().let { parentResult -> + InitializeButtonsFingerprint.resultOrThrow().let { parentResult -> SetPivotBarFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let { it.mutableMethod.apply { val startIndex = it.scanResult.patternScanResult!!.startIndex diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/InitializeButtonsFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PivotBarCreateButtonViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/InitializeButtonsFingerprint.kt index 04e406e4b..e5c160ea1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/PivotBarCreateButtonViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fingerprints/InitializeButtonsFingerprint.kt @@ -5,8 +5,9 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Image import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal object PivotBarCreateButtonViewFingerprint : LiteralValueFingerprint( - returnType = "V", +internal object InitializeButtonsFingerprint : LiteralValueFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = emptyList(), literalSupplier = { ImageOnlyTab } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt index 7a985dcb4..b27f6c831 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt @@ -1,12 +1,12 @@ package app.revanced.patches.youtube.utils.flyoutpanel -import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.or import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patches.youtube.utils.flyoutpanel.fingerprints.PlaybackRateBottomSheetClassFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt new file mode 100644 index 000000000..1eeab6ae0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/NavigationBarHookPatch.kt @@ -0,0 +1,138 @@ +package app.revanced.patches.youtube.utils.navigation + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH +import app.revanced.patches.youtube.utils.navigation.fingerprints.ActionBarSearchResultsFingerprint +import app.revanced.patches.youtube.utils.navigation.fingerprints.NavigationEnumFingerprint +import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButtonsCreateDrawableViewFingerprint +import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarButtonsCreateResourceViewFingerprint +import app.revanced.patches.youtube.utils.navigation.fingerprints.PivotBarConstructorFingerprint +import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.util.getReference +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +@Patch( + description = "Hooks the active navigation or search bar.", + dependencies = [ + PlayerTypeHookPatch::class, + SharedResourceIdPatch::class + ], +) +@Suppress("unused") +object NavigationBarHookPatch : BytecodePatch( + setOf( + ActionBarSearchResultsFingerprint, + NavigationEnumFingerprint, + PivotBarButtonsCreateDrawableViewFingerprint, + PivotBarButtonsCreateResourceViewFingerprint, + PivotBarConstructorFingerprint + ), +) { + internal const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$INTEGRATIONS_PATH/shared/NavigationBar;" + + private const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR = + "$INTEGRATIONS_PATH/shared/NavigationBar\$NavigationButton;" + + private lateinit var navigationTabCreatedCallback: MutableMethod + + override fun execute(context: BytecodeContext) { + fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) { + val filtered = getInstructions().filter(insertPredicate) + if (filtered.isEmpty()) throw PatchException("Could not find insert indexes") + filtered.forEach { + val insertIndex = it.location.index + 2 + val register = getInstruction(insertIndex - 1).registerA + + addInstruction( + insertIndex, + "invoke-static { v$register }, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V", + ) + } + } + + InitializeButtonsFingerprint.apply { + resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef) + }.resultOrThrow().mutableMethod.apply { + // Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value. + val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type + addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) { + opcode == Opcode.INVOKE_STATIC && + getReference()?.definingClass == navigationEnumClassName + } + + // Hook the creation of navigation tab views. + val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod + addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{ + MethodUtil.methodSignaturesMatch( + getReference() ?: return@predicate false, + drawableTabMethod, + ) + } + + val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method + addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{ + MethodUtil.methodSignaturesMatch( + getReference() ?: return@predicate false, + imageResourceTabMethod, + ) + } + } + + // Hook the search bar. + + // Two different layouts are used at the hooked code. + // Insert before the first ViewGroup method call after inflating, + // so this works regardless which layout is used. + ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply { + val instructionIndex = getTargetIndexWithMethodReferenceName("setLayoutDirection") + val viewRegister = getInstruction(instructionIndex).registerC + + addInstruction( + instructionIndex, + "invoke-static { v$viewRegister }, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", + ) + } + + navigationTabCreatedCallback = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method -> + method.name == "navigationTabCreatedCallback" + } ?: throw PatchException("Could not find navigationTabCreatedCallback method") + } + + val hookNavigationButtonCreated: (String) -> Unit by lazy { + navigationTabCreatedCallback + { integrationsClassDescriptor -> + navigationTabCreatedCallback.addInstruction( + 0, + "invoke-static { p0, p1 }, " + + "$integrationsClassDescriptor->navigationTabCreated" + + "(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V", + ) + } + } + + private enum class Hook(val methodName: String, val parameters: String) { + SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"), + NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"), + NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"), + SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"), + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt new file mode 100644 index 000000000..40310aa73 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.utils.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarSearchResultsViewMic +import app.revanced.util.fingerprint.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object ActionBarSearchResultsFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/view/View;", + parameters = listOf("Landroid/view/LayoutInflater;"), + literalSupplier = { ActionBarSearchResultsViewMic } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/NavigationEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/NavigationEnumFingerprint.kt new file mode 100644 index 000000000..76e268ff0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/NavigationEnumFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.youtube.utils.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves to the Enum class that looks up ordinal -> instance. + */ +internal object NavigationEnumFingerprint : MethodFingerprint( + accessFlags = AccessFlags.STATIC or AccessFlags.CONSTRUCTOR, + strings = listOf( + "PIVOT_HOME", + "TAB_SHORTS", + "CREATION_TAB_LARGE", + "PIVOT_SUBSCRIPTIONS", + "TAB_ACTIVITY", + "VIDEO_LIBRARY_WHITE", + "INCOGNITO_CIRCLE" + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt new file mode 100644 index 000000000..5eb84ecdf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.utils.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PivotBarButtonsCreateDrawableViewFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + // Method has different number of parameters in some app targets. + // Parameters are checked in custom fingerprint. + returnType = "Landroid/view/View;", + customFingerprint = { methodDef, classDef -> + classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" && + // Only one method has a Drawable parameter. + methodDef.parameterTypes.firstOrNull() == "Landroid/graphics/drawable/Drawable;" + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt new file mode 100644 index 000000000..709d184ae --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.utils.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PivotBarButtonsCreateResourceViewFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Z", "I", "L"), + returnType = "Landroid/view/View;", + customFingerprint = { _, classDef -> + classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarConstructorFingerprint.kt new file mode 100644 index 000000000..1e6fe82a6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/navigation/fingerprints/PivotBarConstructorFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.youtube.utils.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PivotBarConstructorFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + strings = listOf("com.google.android.apps.youtube.app.endpoint.flags") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index a9a87c376..4f3532e26 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -18,6 +18,7 @@ import app.revanced.patches.shared.mapping.ResourceType.STYLE object SharedResourceIdPatch : ResourcePatch() { var AccountSwitcherAccessibility = -1L var ActionBarRingo = -1L + var ActionBarSearchResultsViewMic = -1L var AdAttribution = -1L var Appearance = -1L var AppRelatedEndScreenResults = -1L @@ -92,6 +93,7 @@ object SharedResourceIdPatch : ResourcePatch() { AccountSwitcherAccessibility = getId(STRING, "account_switcher_accessibility_label") ActionBarRingo = getId(LAYOUT, "action_bar_ringo") + ActionBarSearchResultsViewMic = getId(LAYOUT, "action_bar_search_results_view_mic") AdAttribution = getId(ID, "ad_attribution") Appearance = getId(STRING, "app_theme_appearance_dark") AppRelatedEndScreenResults = getId(LAYOUT, "app_related_endscreen_results") diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index ea3085eea..4ad60e2c3 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -82,7 +82,7 @@ Tap here to learn more about DeArrow." Channel bar Channel profile Comments - Configure which components to filter, separated by new lines. + List of component path builder strings to filter separated by new line. Edit custom filter Invalid custom filter: %s. Custom filter is disabled. @@ -475,6 +475,33 @@ Some components may not be hidden." Join button is shown. Join button is hidden. Hide join button + + + Hide keyword content + Hide search and feed videos using keyword filters. + Hide home videos by keywords + Videos in the home tab are filtered by keywords. + Videos in the home tab are not filtered by keywords. + Hide subscription videos by keywords + Videos in the subscriptions tab are filtered by keywords. + Videos in the subscriptions tab are not filtered by keywords. + Hide search results by keywords + Search results are filtered by keywords. + Search results are not filtered by keywords. + Keywords to hide + "Keywords and phrases to hide, separated by new lines. +Words with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)." + About keyword filtering + "Home / Subscription / Search results are filtered to hide content that matches keyword phrases. + +Limitations: +• Some Shorts may not be hidden. +• Some UI components may not be hidden. +• Searching for a keyword may show no results." + Invalid keyword. Cannot use: \'%s\' as a filter + Invalid keyword. \'%1$s\' is less than %2$d characters + + Latest posts are shown. Latest posts are hidden. Hide latest posts @@ -848,12 +875,12 @@ Known issues: Swipe overlay text size The amount of milliseconds the overlay is visible. Swipe overlay timeout - "Swap the positions of the create button and notification button by spoofing the device's information. + "Switch the positions of the create button and notification button by spoofing device information. • Even if you change this setting, it may not take effect until you reboot the device. • Disabling this setting loads more ads from the server side. • You should disable this setting to make video ads visible." - Switch create with notifications button + Switch create with notifications Tool used Video diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 4caaf5000..ab550493c 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -264,6 +264,14 @@ + SETTINGS: HIDE_NAVIGATION_BUTTONS -->