From b8858f7853ee3453ab9e9f6fc068d80eeae55c92 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Thu, 15 Feb 2024 23:48:44 +0400
Subject: [PATCH 01/26] feat(YouTube): Add `Hide keyword content` patch
---
api/revanced-patches.api | 6 ++
.../hide/keyword/HideKeywordContentPatch.kt | 57 +++++++++++++++++++
.../resources/addresources/values/strings.xml | 12 ++++
3 files changed, 75 insertions(+)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
diff --git a/api/revanced-patches.api b/api/revanced-patches.api
index 4e1ad810a5..4d325dac79 100644
--- a/api/revanced-patches.api
+++ b/api/revanced-patches.api
@@ -1350,6 +1350,12 @@ public final class app/revanced/patches/youtube/layout/hide/infocards/HideInfoca
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
+public final class app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch : app/revanced/patcher/patch/BytecodePatch {
+ public static final field INSTANCE Lapp/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch;
+ public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
+ public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
+}
+
public final class app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
new file mode 100644
index 0000000000..ed76a910ca
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
@@ -0,0 +1,57 @@
+package app.revanced.patches.youtube.layout.hide.keyword
+
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.patch.BytecodePatch
+import app.revanced.patcher.patch.annotation.CompatiblePackage
+import app.revanced.patcher.patch.annotation.Patch
+import app.revanced.patches.all.misc.resources.AddResourcesPatch
+import app.revanced.patches.shared.misc.settings.preference.InputType
+import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
+import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
+import app.revanced.patches.shared.misc.settings.preference.TextPreference
+import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
+import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
+import app.revanced.patches.youtube.misc.settings.SettingsPatch
+
+@Patch(
+ name = "Hide keyword content",
+ description = "Adds options to hide home feed or search results based on keywords",
+ dependencies = [IntegrationsPatch::class, SettingsPatch::class, LithoFilterPatch::class],
+ compatiblePackages = [
+ CompatiblePackage(
+ "com.google.android.youtube", [
+ "18.43.45",
+ "18.44.41",
+ "18.45.43",
+ "18.48.39",
+ "18.49.37",
+ "19.01.34",
+ "19.02.39",
+ "19.03.35",
+ "19.03.36",
+ "19.04.37"
+ ]
+ )
+ ]
+)
+@Suppress("unused")
+object HideKeywordContentPatch : BytecodePatch(emptySet()) {
+ private const val FILTER_CLASS_DESCRIPTOR =
+ "Lapp/revanced/integrations/youtube/patches/components/HideKeywordContentFilter;"
+
+ override fun execute(context: BytecodeContext) {
+ AddResourcesPatch(this::class)
+
+ SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
+ PreferenceScreen(
+ key = "revanced_hide_keyword_content_preference_screen",
+ preferences = setOf(
+ SwitchPreference("revanced_hide_keyword_content"),
+ TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
+ ),
+ )
+ )
+
+ LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
+ }
+}
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index c473143626..051930552e 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -431,6 +431,18 @@
Microphone button hidden
Microphone button shown
+
+ Hide keyword content
+ Hide home/search result videos with keyword filters
+ Enable keyword filtering
+ Home/search is filtered to hide content matching keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Searching for a keyword may give no search results\n• Some Shorts may not be hidden
+ Home/search results are not filtered
+ Keywords to hide
+ Keyword and phrases to hide, separated by new lines\n\nKeywords specified here automatically include some uppercase and lowercase variations, but some keywords require entering the exact casing (ie: \'LeBlanc\', \'Van Der Berg\', etc)
+ Invalid keyword phrase (must be ASCII only): %s
+ Invalid keyword length (must be at least %s characters): %s
+ Keywords reset to default
+
Disable ambient mode in fullscreen
Ambient mode disabled
From 9cd5a63422c573688acca53dd631bdf6a64ca050 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Fri, 8 Mar 2024 11:13:06 +0400
Subject: [PATCH 02/26] refactor: move code into `HideLayoutComponents`
---
api/revanced-patches.api | 6 --
.../hide/general/HideLayoutComponentsPatch.kt | 13 +++++
.../hide/keyword/HideKeywordContentPatch.kt | 57 -------------------
.../resources/addresources/values/strings.xml | 22 ++++---
4 files changed, 23 insertions(+), 75 deletions(-)
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
diff --git a/api/revanced-patches.api b/api/revanced-patches.api
index 4d325dac79..4e1ad810a5 100644
--- a/api/revanced-patches.api
+++ b/api/revanced-patches.api
@@ -1350,12 +1350,6 @@ public final class app/revanced/patches/youtube/layout/hide/infocards/HideInfoca
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
-public final class app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch : app/revanced/patcher/patch/BytecodePatch {
- public static final field INSTANCE Lapp/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch;
- public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
- public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
-}
-
public final class app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index f72d80a324..61e00eb330 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -65,6 +65,8 @@ object HideLayoutComponentsPatch : BytecodePatch(
"Lapp/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter;"
private const val CUSTOM_FILTER_CLASS_NAME =
"Lapp/revanced/integrations/youtube/patches/components/CustomFilter;"
+ private const val KEYWORD_FILTER_CLASS_NAME =
+ "Lapp/revanced/integrations/youtube/patches/components/HideKeywordContentFilter;"
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
@@ -113,6 +115,16 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_search_result_shelf_header"),
)
+ SettingsPatch.PreferenceScreen.FEED.addPreferences(
+ PreferenceScreen(
+ key = "revanced_hide_keyword_content_preference_screen",
+ preferences = setOf(
+ SwitchPreference("revanced_hide_keyword_content"),
+ TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
+ ),
+ )
+ )
+
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_gray_separator"),
PreferenceScreen(
@@ -132,6 +144,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
LithoFilterPatch.addFilter(DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME)
+ LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME)
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_NAME)
// region Mix playlists
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
deleted file mode 100644
index ed76a910ca..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/keyword/HideKeywordContentPatch.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package app.revanced.patches.youtube.layout.hide.keyword
-
-import app.revanced.patcher.data.BytecodeContext
-import app.revanced.patcher.patch.BytecodePatch
-import app.revanced.patcher.patch.annotation.CompatiblePackage
-import app.revanced.patcher.patch.annotation.Patch
-import app.revanced.patches.all.misc.resources.AddResourcesPatch
-import app.revanced.patches.shared.misc.settings.preference.InputType
-import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
-import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
-import app.revanced.patches.shared.misc.settings.preference.TextPreference
-import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
-import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
-import app.revanced.patches.youtube.misc.settings.SettingsPatch
-
-@Patch(
- name = "Hide keyword content",
- description = "Adds options to hide home feed or search results based on keywords",
- dependencies = [IntegrationsPatch::class, SettingsPatch::class, LithoFilterPatch::class],
- compatiblePackages = [
- CompatiblePackage(
- "com.google.android.youtube", [
- "18.43.45",
- "18.44.41",
- "18.45.43",
- "18.48.39",
- "18.49.37",
- "19.01.34",
- "19.02.39",
- "19.03.35",
- "19.03.36",
- "19.04.37"
- ]
- )
- ]
-)
-@Suppress("unused")
-object HideKeywordContentPatch : BytecodePatch(emptySet()) {
- private const val FILTER_CLASS_DESCRIPTOR =
- "Lapp/revanced/integrations/youtube/patches/components/HideKeywordContentFilter;"
-
- override fun execute(context: BytecodeContext) {
- AddResourcesPatch(this::class)
-
- SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
- PreferenceScreen(
- key = "revanced_hide_keyword_content_preference_screen",
- preferences = setOf(
- SwitchPreference("revanced_hide_keyword_content"),
- TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
- ),
- )
- )
-
- LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
- }
-}
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index 051930552e..da09bdd000 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -170,6 +170,16 @@
Invalid custom filter (must be ASCII only): %s
Invalid custom filter: %s
Custom filter reset to default
+ Hide keyword content
+ Hide feed and search result videos using keyword filters
+ Enable keyword filtering
+ Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Some Shorts may not be hidden\n• Searching for a keyword may show no results
+ Feed/search results are not filtered
+ Keywords to hide
+ Keywords and phrases to hide, separated by new lines.\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering the exact casing (ie: LeBlanc, John Doe, etc)
+ Invalid keyword phrase (must be ASCII only): %s
+ Invalid keyword length (must be at least %s characters): %s
+ Keywords reset to default
Hide general ads
@@ -431,18 +441,6 @@
Microphone button hidden
Microphone button shown
-
- Hide keyword content
- Hide home/search result videos with keyword filters
- Enable keyword filtering
- Home/search is filtered to hide content matching keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Searching for a keyword may give no search results\n• Some Shorts may not be hidden
- Home/search results are not filtered
- Keywords to hide
- Keyword and phrases to hide, separated by new lines\n\nKeywords specified here automatically include some uppercase and lowercase variations, but some keywords require entering the exact casing (ie: \'LeBlanc\', \'Van Der Berg\', etc)
- Invalid keyword phrase (must be ASCII only): %s
- Invalid keyword length (must be at least %s characters): %s
- Keywords reset to default
-
Disable ambient mode in fullscreen
Ambient mode disabled
From cc19666b5803fb1da08c349b7a01b12cb7988cfb Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Fri, 8 Mar 2024 17:29:12 +0400
Subject: [PATCH 03/26] feat: Support unicode keyword and custom filters
---
src/main/resources/addresources/values/strings.xml | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index da09bdd000..b5003b08eb 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -167,7 +167,6 @@
Custom filter is disabled
Custom filter
List of component path builder strings to filter separated by new line
- Invalid custom filter (must be ASCII only): %s
Invalid custom filter: %s
Custom filter reset to default
Hide keyword content
@@ -177,7 +176,6 @@
Feed/search results are not filtered
Keywords to hide
Keywords and phrases to hide, separated by new lines.\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering the exact casing (ie: LeBlanc, John Doe, etc)
- Invalid keyword phrase (must be ASCII only): %s
Invalid keyword length (must be at least %s characters): %s
Keywords reset to default
From 2c65188684c83eca87e7968bab1f443341a9b966 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Fri, 8 Mar 2024 18:40:39 +0400
Subject: [PATCH 04/26] fix: Use unsorted
---
.../youtube/layout/hide/general/HideLayoutComponentsPatch.kt | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index 61e00eb330..75f1ebf7b5 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -118,6 +118,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SettingsPatch.PreferenceScreen.FEED.addPreferences(
PreferenceScreen(
key = "revanced_hide_keyword_content_preference_screen",
+ sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_hide_keyword_content"),
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
From f6bc93650f1301cf4f0a301f847b2354d46a1bc3 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Fri, 8 Mar 2024 21:20:15 +0400
Subject: [PATCH 05/26] adjust text
---
src/main/resources/addresources/values/strings.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index b5003b08eb..a8c42b0561 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -175,7 +175,7 @@
Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Some Shorts may not be hidden\n• Searching for a keyword may show no results
Feed/search results are not filtered
Keywords to hide
- Keywords and phrases to hide, separated by new lines.\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering the exact casing (ie: LeBlanc, John Doe, etc)
+ Keywords and phrases to hide, separated by new lines\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering exact casing (ie: LeBlanc, John Doe)
Invalid keyword length (must be at least %s characters): %s
Keywords reset to default
From bc25b65dd375d713ca34669ebd846b75816bcc6d Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sat, 9 Mar 2024 17:37:23 +0400
Subject: [PATCH 06/26] fix: Do not reset keywords or custom filter. Show a
toast and leave as-is for the user to fix.
---
src/main/resources/addresources/values/strings.xml | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index a8c42b0561..b7904ab37d 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -168,7 +168,6 @@
Custom filter
List of component path builder strings to filter separated by new line
Invalid custom filter: %s
- Custom filter reset to default
Hide keyword content
Hide feed and search result videos using keyword filters
Enable keyword filtering
@@ -177,7 +176,6 @@
Keywords to hide
Keywords and phrases to hide, separated by new lines\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering exact casing (ie: LeBlanc, John Doe)
Invalid keyword length (must be at least %s characters): %s
- Keywords reset to default
Hide general ads
From dfc8e886283aae840ff76a0c262df48fb9af542c Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sat, 9 Mar 2024 18:24:37 +0400
Subject: [PATCH 07/26] fix: Automatically filter capitalized first letter of
each sentence.
---
src/main/resources/addresources/values/strings.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index b7904ab37d..1c4c2638ee 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -174,7 +174,7 @@
Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Some Shorts may not be hidden\n• Searching for a keyword may show no results
Feed/search results are not filtered
Keywords to hide
- Keywords and phrases to hide, separated by new lines\n\nText specified here automatically include some uppercase and lowercase variations, but some text requires entering exact casing (ie: LeBlanc, John Doe)
+ Keywords and phrases to hide, separated by new lines\n\nKeywords or phrases with mix casing must include the casing (ie: LeBlanc, DeAndre, TikTok)
Invalid keyword length (must be at least %s characters): %s
From 86f24c82c0b56f043b348e66708850e0dac81c6f Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sat, 9 Mar 2024 18:33:41 +0400
Subject: [PATCH 08/26] refactor: Rename class
---
.../youtube/layout/hide/general/HideLayoutComponentsPatch.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index 75f1ebf7b5..e5cc588800 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -66,7 +66,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
private const val CUSTOM_FILTER_CLASS_NAME =
"Lapp/revanced/integrations/youtube/patches/components/CustomFilter;"
private const val KEYWORD_FILTER_CLASS_NAME =
- "Lapp/revanced/integrations/youtube/patches/components/HideKeywordContentFilter;"
+ "Lapp/revanced/integrations/youtube/patches/components/KeywordContentFilter;"
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
From e82f6a2de7ae5b47a1c1f214e06e35c046167ac4 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sun, 10 Mar 2024 19:40:40 +0400
Subject: [PATCH 09/26] fix: adjust settings text
---
src/main/resources/addresources/values/strings.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index 1c4c2638ee..5f7558a4fa 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -172,9 +172,9 @@
Hide feed and search result videos using keyword filters
Enable keyword filtering
Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Some Shorts may not be hidden\n• Searching for a keyword may show no results
- Feed/search results are not filtered
+ Feed/search results are not filtered by keywords
Keywords to hide
- Keywords and phrases to hide, separated by new lines\n\nKeywords or phrases with mix casing must include the casing (ie: LeBlanc, DeAndre, TikTok)
+ Keywords and phrases to hide, separated by new lines\n\nWords with unusual upper/lower case usage must include the casing (ie: LeBlanc, DeAndre, TikTok)
Invalid keyword length (must be at least %s characters): %s
From d89490be3347048406044be50c82b4ec1b325bae Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Mon, 11 Mar 2024 17:35:03 +0400
Subject: [PATCH 10/26] fix: adjust settings text
---
src/main/resources/addresources/values/strings.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index 5f7558a4fa..12db801a4d 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -171,10 +171,10 @@
Hide keyword content
Hide feed and search result videos using keyword filters
Enable keyword filtering
- Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some UI elements may not be hidden\n• Some Shorts may not be hidden\n• Searching for a keyword may show no results
+ Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI elements may not be hidden\n• Searching for a keyword may show no results
Feed/search results are not filtered by keywords
Keywords to hide
- Keywords and phrases to hide, separated by new lines\n\nWords with unusual upper/lower case usage must include the casing (ie: LeBlanc, DeAndre, TikTok)
+ Keywords and phrases to hide, separated by new lines\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)
Invalid keyword length (must be at least %s characters): %s
From 944b7550cb82adffda499ede9df07cdc4cba721d Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Thu, 14 Mar 2024 13:02:45 +0400
Subject: [PATCH 11/26] feat: Selective filtering of search/home/subscriptions
---
.../navigation/NavigationButtonsPatch.kt | 47 ++++++++++++++-----
.../ResolvePivotBarFingerprintsPatch.kt | 13 +++--
.../ActionBarSearchResultsFingerprint.kt | 13 +++++
.../navigation/utils/InjectionUtils.kt | 2 +-
.../hide/general/HideLayoutComponentsPatch.kt | 14 ++++--
.../resources/addresources/values/strings.xml | 18 +++++--
6 files changed, 82 insertions(+), 25 deletions(-)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index 94e67f73b3..117aad8134 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.layout.buttons.navigation
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.patch.BytecodePatch
@@ -16,8 +17,13 @@ import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUti
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
+import app.revanced.util.getReference
+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.reference.MethodReference
+// TODO: break this patch apart so other patches can check what tab is active (without depending on this patch).
@Patch(
name = "Navigation buttons",
description = "Adds options to hide and change navigation buttons (such as the Shorts button).",
@@ -54,7 +60,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
)
@Suppress("unused")
object NavigationButtonsPatch : BytecodePatch(
- setOf(AddCreateButtonViewFingerprint),
+ setOf(AddCreateButtonViewFingerprint, ActionBarSearchResultsFingerprint),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/NavigationButtonsPatch;"
@@ -106,17 +112,17 @@ object NavigationButtonsPatch : BytecodePatch(
* Inject hooks
*/
- val enumHook = "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->lastNavigationButton:Ljava/lang/Enum;"
+ val enumHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->hideButton(Landroid/view/View;)V"
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
// Inject bottom to top to not mess up the indices
mapOf(
buttonHook to buttonHookInsertIndex,
enumHook to enumHookInsertIndex,
).forEach { (hook, insertIndex) ->
- initializeButtonsResult.mutableMethod.injectHook(hook, insertIndex)
+ initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
}
/*
@@ -154,14 +160,31 @@ object NavigationButtonsPatch : BytecodePatch(
PivotBarCreateButtonViewFingerprint.result!!.apply {
val insertIndex = scanResult.patternScanResult!!.endIndex
+ mutableMethod.injectHook(
+ insertIndex,
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
+ )
+ }
- /*
- * Inject hooks
- */
- val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V"
+ /**
+ * Search bar TextView
+ */
- mutableMethod.injectHook(hook, insertIndex)
- }
+ // 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.result?.mutableMethod?.apply {
+ val instructionIndex = implementation!!.instructions.indexOfFirst {
+ it.opcode == Opcode.INVOKE_VIRTUAL &&
+ it.getReference()?.name == "setLayoutDirection"
+ }
+ val register = getInstruction(instructionIndex).registerC
+ addInstruction(
+ instructionIndex,
+ "invoke-static { v$register }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V"
+ )
+ } ?: ActionBarSearchResultsFingerprint.exception
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
index eacab72b45..3a11960b50 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
@@ -1,13 +1,12 @@
package app.revanced.patches.youtube.layout.buttons.navigation
-import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
-import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.InitializeButtonsFingerprint
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.PivotBarConstructorFingerprint
+import app.revanced.util.exception
@Patch(
description = "Resolves necessary fingerprints.",
@@ -17,11 +16,17 @@ internal object ResolvePivotBarFingerprintsPatch : BytecodePatch(
setOf(PivotBarConstructorFingerprint)
) {
internal var imageOnlyTabResourceId: Long = -1
+ internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: BytecodeContext) {
// imageOnlyTabResourceId is used in InitializeButtonsFingerprint fingerprint
- ResourceMappingPatch.resourceMappings.find { it.type == "layout" && it.name == "image_only_tab" }
- ?.let { imageOnlyTabResourceId = it.id } ?: throw PatchException("Failed to find resource")
+ imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.single {
+ it.type == "layout" && it.name == "image_only_tab"
+ }.id
+
+ actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.single {
+ it.type == "layout" && it.name == "action_bar_search_results_view_mic"
+ }.id
PivotBarConstructorFingerprint.result?.let {
// Resolve InitializeButtonsFingerprint on the class of the method
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
new file mode 100644
index 0000000000..aa25433438
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
@@ -0,0 +1,13 @@
+package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+
+import app.revanced.patcher.extensions.or
+import app.revanced.patches.youtube.layout.buttons.navigation.ResolvePivotBarFingerprintsPatch
+import app.revanced.util.patch.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 = { ResolvePivotBarFingerprintsPatch.actionBarSearchResultsViewMicId }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt
index f97305c12c..e333acb78a 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt
@@ -15,7 +15,7 @@ internal object InjectionUtils {
* @param insertIndex The index to insert the instruction at.
* [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex].
*/
- fun MutableMethod.injectHook(hook: String, insertIndex: Int) {
+ fun MutableMethod.injectHook(insertIndex: Int, hook: String) {
val injectTarget = this
// Register to pass to the hook
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index ad9f6b20d4..ff68576363 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -12,14 +12,17 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.InputType
+import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
+import app.revanced.patches.youtube.layout.buttons.navigation.NavigationButtonsPatch
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
+import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
@@ -33,6 +36,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
+ NavigationButtonsPatch::class, // FIXME: use a sub patch
+ PlayerTypeHookPatch::class // Used by Keyword Content filter.
],
compatiblePackages = [
CompatiblePackage(
@@ -121,12 +126,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
SettingsPatch.PreferenceScreen.FEED.addPreferences(
PreferenceScreen(
- key = "revanced_hide_keyword_content_preference_screen",
+ key = "revanced_hide_keyword_content_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
- SwitchPreference("revanced_hide_keyword_content"),
+ SwitchPreference("revanced_hide_keyword_content_search"),
+ SwitchPreference("revanced_hide_keyword_content_home"),
+ SwitchPreference("revanced_hide_keyword_content_subscriptions"),
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
- ),
+ NonInteractivePreference("revanced_hide_keyword_content_about")
+ )
)
)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index 12db801a4d..f9b51073ff 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -168,13 +168,21 @@
Custom filter
List of component path builder strings to filter separated by new line
Invalid custom filter: %s
- Hide keyword content
- Hide feed and search result videos using keyword filters
- Enable keyword filtering
- Feed/search is filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI elements may not be hidden\n• Searching for a keyword may show no results
- Feed/search results are not filtered by keywords
+ Hide keyword content
+ Hide feed and search result 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 keywordsx
+ Videos in the subscriptions tab are filtered by keywords
+ Videos in the subscriptions tab are not filtered by keywords
+ Hide search results by keywordsx
+ 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\n\nWords 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\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI elements may not be hidden\n• Searching for a keyword may show no results
Invalid keyword length (must be at least %s characters): %s
From 1e2f8a10f2e7e91c7bd2ff54003a894bbcf16566 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Thu, 14 Mar 2024 18:13:25 +0400
Subject: [PATCH 12/26] refactor: break apart NavigationButtonsPatch into
subpatch
---
api/revanced-patches.api | 7 +
.../navigation/NavigationButtonsPatch.kt | 105 ++----------
.../ResolvePivotBarFingerprintsPatch.kt | 42 -----
.../hide/general/HideLayoutComponentsPatch.kt | 4 +-
.../misc/navigation/NavigationBarHookPatch.kt | 151 ++++++++++++++++++
.../NavigationBarHookResourcePatch.kt | 24 +++
.../ActionBarSearchResultsFingerprint.kt | 6 +-
.../InitializeButtonsFingerprint.kt | 9 +-
.../NavigationBarHookCallbackFingerprint.kt | 24 +++
.../PivotBarButtonsViewFingerprint.kt | 5 +-
.../PivotBarConstructorFingerprint.kt | 2 +-
.../PivotBarCreateButtonViewFingerprint.kt | 5 +-
.../fingerprints/PivotBarEnumFingerprint.kt | 5 +-
.../navigation/utils/InjectionUtils.kt | 2 +-
14 files changed, 241 insertions(+), 150 deletions(-)
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt (59%)
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/InitializeButtonsFingerprint.kt (52%)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt (69%)
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/PivotBarConstructorFingerprint.kt (82%)
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt (70%)
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/fingerprints/PivotBarEnumFingerprint.kt (73%)
rename src/main/kotlin/app/revanced/patches/youtube/{layout/buttons => misc}/navigation/utils/InjectionUtils.kt (94%)
diff --git a/api/revanced-patches.api b/api/revanced-patches.api
index 4e1ad810a5..60bfb80d2d 100644
--- a/api/revanced-patches.api
+++ b/api/revanced-patches.api
@@ -1575,6 +1575,13 @@ public final class app/revanced/patches/youtube/misc/minimizedplayback/Minimized
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
+public final class app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch : app/revanced/patcher/patch/BytecodePatch {
+ public static final field INSTANCE Lapp/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch;
+ public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
+ public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
+ public final fun hookNavigationButtonCreated (Ljava/lang/String;)V
+}
+
public final class app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable {
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch;
public final fun addControls (Ljava/lang/String;)V
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index 117aad8134..fd948d35fe 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.buttons.navigation
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.patch.BytecodePatch
@@ -11,27 +10,22 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
-import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.*
-import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
-import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.injectHook
+import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.ANDROID_AUTOMOTIVE_STRING
+import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.AddCreateButtonViewFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
-import app.revanced.util.getReference
-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.reference.MethodReference
-// TODO: break this patch apart so other patches can check what tab is active (without depending on this patch).
@Patch(
name = "Navigation buttons",
description = "Adds options to hide and change navigation buttons (such as the Shorts button).",
dependencies = [
IntegrationsPatch::class,
SettingsPatch::class,
- ResolvePivotBarFingerprintsPatch::class,
AddResourcesPatch::class,
+ NavigationBarHookPatch::class
],
compatiblePackages = [
CompatiblePackage(
@@ -60,10 +54,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
)
@Suppress("unused")
object NavigationButtonsPatch : BytecodePatch(
- setOf(AddCreateButtonViewFingerprint, ActionBarSearchResultsFingerprint),
+ setOf(AddCreateButtonViewFingerprint),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
- "Lapp/revanced/integrations/youtube/patches/NavigationButtonsPatch;"
+ "Lapp/revanced/integrations/youtube/patches/HideNavigationButtonsPatch;"
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
@@ -83,50 +77,7 @@ object NavigationButtonsPatch : BytecodePatch(
)
/*
- * Resolve fingerprints
- */
-
- val initializeButtonsResult = InitializeButtonsFingerprint.result!!
-
- val fingerprintResults =
- arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint)
- .onEach {
- if (!it.resolve(
- context,
- initializeButtonsResult.mutableMethod,
- initializeButtonsResult.mutableClass,
- )
- ) {
- throw it.exception
- }
- }
- .map { it.result!!.scanResult.patternScanResult!! }
-
- val enumScanResult = fingerprintResults[0]
- val buttonViewResult = fingerprintResults[1]
-
- val enumHookInsertIndex = enumScanResult.startIndex + 2
- val buttonHookInsertIndex = buttonViewResult.endIndex
-
- /*
- * Inject hooks
- */
-
- val enumHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
- val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
-
- // Inject bottom to top to not mess up the indices
- mapOf(
- buttonHook to buttonHookInsertIndex,
- enumHook to enumHookInsertIndex,
- ).forEach { (hook, insertIndex) ->
- initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
- }
-
- /*
- * Hide create or switch it with notifications buttons.
+ * Switch create button with notification.
*/
AddCreateButtonViewFingerprint.result?.let {
@@ -136,7 +87,8 @@ object NavigationButtonsPatch : BytecodePatch(
}!!.index
val conditionalCheckIndex = stringIndex - 1
- val conditionRegister = getInstruction(conditionalCheckIndex).registerA
+ val conditionRegister =
+ getInstruction(conditionalCheckIndex).registerA
addInstructions(
conditionalCheckIndex,
@@ -148,43 +100,6 @@ object NavigationButtonsPatch : BytecodePatch(
}
} ?: throw AddCreateButtonViewFingerprint.exception
- /*
- * Resolve fingerprints
- */
-
- InitializeButtonsFingerprint.result!!.let {
- if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) {
- throw PivotBarCreateButtonViewFingerprint.exception
- }
- }
-
- PivotBarCreateButtonViewFingerprint.result!!.apply {
- val insertIndex = scanResult.patternScanResult!!.endIndex
- mutableMethod.injectHook(
- insertIndex,
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
- )
- }
-
- /**
- * Search bar TextView
- */
-
- // 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.result?.mutableMethod?.apply {
- val instructionIndex = implementation!!.instructions.indexOfFirst {
- it.opcode == Opcode.INVOKE_VIRTUAL &&
- it.getReference()?.name == "setLayoutDirection"
- }
- val register = getInstruction(instructionIndex).registerC
- addInstruction(
- instructionIndex,
- "invoke-static { v$register }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V"
- )
- } ?: ActionBarSearchResultsFingerprint.exception
+ NavigationBarHookPatch.hookNavigationButtonCreated(INTEGRATIONS_CLASS_DESCRIPTOR)
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
deleted file mode 100644
index 3a11960b50..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package app.revanced.patches.youtube.layout.buttons.navigation
-
-import app.revanced.patcher.data.BytecodeContext
-import app.revanced.patcher.patch.BytecodePatch
-import app.revanced.patcher.patch.annotation.Patch
-import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
-import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.InitializeButtonsFingerprint
-import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.PivotBarConstructorFingerprint
-import app.revanced.util.exception
-
-@Patch(
- description = "Resolves necessary fingerprints.",
- dependencies = [ResourceMappingPatch::class]
-)
-internal object ResolvePivotBarFingerprintsPatch : BytecodePatch(
- setOf(PivotBarConstructorFingerprint)
-) {
- internal var imageOnlyTabResourceId: Long = -1
- internal var actionBarSearchResultsViewMicId: Long = -1
-
- override fun execute(context: BytecodeContext) {
- // imageOnlyTabResourceId is used in InitializeButtonsFingerprint fingerprint
- imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.single {
- it.type == "layout" && it.name == "image_only_tab"
- }.id
-
- actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.single {
- it.type == "layout" && it.name == "action_bar_search_results_view_mic"
- }.id
-
- PivotBarConstructorFingerprint.result?.let {
- // Resolve InitializeButtonsFingerprint on the class of the method
- // which PivotBarConstructorFingerprint resolved to
- if (!InitializeButtonsFingerprint.resolve(
- context,
- it.classDef
- )
- ) throw InitializeButtonsFingerprint.exception
- } ?: throw PivotBarConstructorFingerprint.exception
- }
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index ff68576363..487c88ad92 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -17,7 +17,7 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
-import app.revanced.patches.youtube.layout.buttons.navigation.NavigationButtonsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
@@ -36,7 +36,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
- NavigationButtonsPatch::class, // FIXME: use a sub patch
+ NavigationBarHookPatch::class,
PlayerTypeHookPatch::class // Used by Keyword Content filter.
],
compatiblePackages = [
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
new file mode 100644
index 0000000000..0bce6d4ce8
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -0,0 +1,151 @@
+package app.revanced.patches.youtube.misc.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.patch.BytecodePatch
+import app.revanced.patcher.patch.annotation.Patch
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
+import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
+import app.revanced.patches.youtube.misc.navigation.fingerprints.ActionBarSearchResultsFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.InitializeButtonsFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.NavigationBarHookCallbackFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsViewFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarConstructorFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarCreateButtonViewFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarEnumFingerprint
+import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
+import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHook
+import app.revanced.util.exception
+import app.revanced.util.getReference
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.reference.MethodReference
+
+@Patch(
+ description = "Hook to get the current navigation bar tab that is active, and if the search bar is active.",
+ dependencies = [
+ IntegrationsPatch::class,
+ NavigationBarHookResourcePatch::class
+ ]
+)
+@Suppress("unused")
+object NavigationBarHookPatch : BytecodePatch(
+ setOf(
+ PivotBarConstructorFingerprint,
+ ActionBarSearchResultsFingerprint,
+ NavigationBarHookCallbackFingerprint
+ )
+) {
+ internal const val INTEGRATIONS_CLASS_DESCRIPTOR =
+ "Lapp/revanced/integrations/youtube/shared/NavigationBar;"
+
+ internal const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR =
+ "Lapp/revanced/integrations/youtube/shared/NavigationBar\$NavigationButton;"
+
+ private lateinit var navigationTabCreatedCallbackMethod: MutableMethod
+
+ override fun execute(context: BytecodeContext) {
+ PivotBarConstructorFingerprint.result?.let {
+ InitializeButtonsFingerprint.resolve(
+ context,
+ it.classDef
+ )
+ } ?: throw PivotBarConstructorFingerprint.exception
+
+ val initializeButtonsResult = InitializeButtonsFingerprint.result
+ ?: throw InitializeButtonsFingerprint.exception
+
+ val fingerprintResults =
+ arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint)
+ .onEach {
+ if (!it.resolve(
+ context,
+ initializeButtonsResult.mutableMethod,
+ initializeButtonsResult.mutableClass,
+ )
+ ) {
+ throw it.exception
+ }
+ }
+ .map { it.result!!.scanResult.patternScanResult!! }
+
+ val enumScanResult = fingerprintResults[0]
+ val buttonViewResult = fingerprintResults[1]
+
+ val enumHookInsertIndex = enumScanResult.startIndex + 2
+ val buttonHookInsertIndex = buttonViewResult.endIndex
+
+ /*
+ * Inject hooks
+ */
+
+ val enumHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
+ val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
+
+ // Inject bottom to top to not mess up the indices
+ mapOf(
+ buttonHook to buttonHookInsertIndex,
+ enumHook to enumHookInsertIndex,
+ ).forEach { (hook, insertIndex) ->
+ initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
+ }
+
+ InitializeButtonsFingerprint.result?.let {
+ if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) {
+ throw PivotBarCreateButtonViewFingerprint.exception
+ }
+ } ?: throw InitializeButtonsFingerprint.exception
+
+ /**
+ * Unique hook just for the Create tab button.
+ */
+ PivotBarCreateButtonViewFingerprint.result?.apply {
+ val insertIndex = scanResult.patternScanResult!!.endIndex
+ mutableMethod.injectHook(
+ insertIndex,
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
+ )
+ } ?: PivotBarCreateButtonViewFingerprint.exception
+
+
+ /**
+ * Callback for other patches.
+ */
+ NavigationBarHookCallbackFingerprint.result?.apply {
+ navigationTabCreatedCallbackMethod = mutableMethod
+ } ?: NavigationBarHookCallbackFingerprint.exception
+
+
+ /**
+ * 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.result?.mutableMethod?.apply {
+ val instructionIndex = implementation!!.instructions.indexOfFirst {
+ it.opcode == Opcode.INVOKE_VIRTUAL &&
+ it.getReference()?.name == "setLayoutDirection"
+ }
+ val register = getInstruction(instructionIndex).registerC
+ addInstruction(
+ instructionIndex,
+ "invoke-static { v$register }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V"
+ )
+ } ?: ActionBarSearchResultsFingerprint.exception
+ }
+
+ fun hookNavigationButtonCreated(classDescriptor: String) {
+ navigationTabCreatedCallbackMethod.addInstruction(
+ 0,
+ "invoke-static { p0, p1 }, " +
+ "$classDescriptor->navigationTabCreated(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V"
+ )
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
new file mode 100644
index 0000000000..fc515fd359
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
@@ -0,0 +1,24 @@
+package app.revanced.patches.youtube.misc.navigation
+
+import app.revanced.patcher.data.ResourceContext
+import app.revanced.patcher.patch.ResourcePatch
+import app.revanced.patcher.patch.annotation.Patch
+import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
+
+@Patch(
+ dependencies = [ResourceMappingPatch::class]
+)
+internal object NavigationBarHookResourcePatch : ResourcePatch() {
+ internal var imageOnlyTabResourceId: Long = -1
+ internal var actionBarSearchResultsViewMicId: Long = -1
+
+ override fun execute(context: ResourceContext) {
+ imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.single {
+ it.type == "layout" && it.name == "image_only_tab"
+ }.id
+
+ actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.single {
+ it.type == "layout" && it.name == "action_bar_search_results_view_mic"
+ }.id
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
similarity index 59%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
index aa25433438..2ba8106f99 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt
@@ -1,7 +1,7 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patches.youtube.layout.buttons.navigation.ResolvePivotBarFingerprintsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
@@ -9,5 +9,5 @@ internal object ActionBarSearchResultsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Landroid/view/View;",
parameters = listOf("Landroid/view/LayoutInflater;"),
- literalSupplier = { ResolvePivotBarFingerprintsPatch.actionBarSearchResultsViewMicId }
+ literalSupplier = { NavigationBarHookResourcePatch.actionBarSearchResultsViewMicId }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt
similarity index 52%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt
index f64015c78a..f91d1b36f3 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt
@@ -1,13 +1,16 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patches.youtube.layout.buttons.navigation.ResolvePivotBarFingerprintsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
+/**
+ * Resolves to the class found in [PivotBarConstructorFingerprint].
+ */
internal object InitializeButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf(),
- literalSupplier = { ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId }
+ literalSupplier = { NavigationBarHookResourcePatch.imageOnlyTabResourceId }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
new file mode 100644
index 0000000000..6cc2f8aa3b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
@@ -0,0 +1,24 @@
+package app.revanced.patches.youtube.misc.navigation.fingerprints
+
+import app.revanced.patcher.extensions.or
+import app.revanced.patcher.fingerprint.MethodFingerprint
+import app.revanced.patches.youtube.layout.buttons.navigation.NavigationButtonsPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
+import com.android.tools.smali.dexlib2.AccessFlags
+
+/**
+ * Integrations method, used for callback into to other patches.
+ * Specifically, [NavigationButtonsPatch].
+ */
+internal object NavigationBarHookCallbackFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
+ returnType = "V",
+ parameters = listOf(
+ NavigationBarHookPatch.INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR,
+ "Landroid/view/View;"
+ ),
+ customFingerprint = { methodDef, _ ->
+ methodDef.name == "navigationTabCreatedCallback"
+ && methodDef.definingClass == NavigationBarHookPatch.INTEGRATIONS_CLASS_DESCRIPTOR
+ }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
similarity index 69%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
index 7827a4f4f4..cb8328dff8 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
@@ -1,8 +1,11 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
+/**
+ * Resolves to the method found in [InitializeButtonsFingerprint].
+ */
internal object PivotBarButtonsViewFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL_RANGE,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt
similarity index 82%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt
index 37674a2bfc..57bc63e4d5 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt
@@ -1,4 +1,4 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
similarity index 70%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
index a32ee0cb71..f438eea73e 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
@@ -1,8 +1,11 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
+/**
+ * Resolves to the method found in [InitializeButtonsFingerprint].
+ */
internal object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_DIRECT_RANGE,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
similarity index 73%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
index df40cc9eb8..864873aa70 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
@@ -1,8 +1,11 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
+package app.revanced.patches.youtube.misc.navigation.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
+/**
+ * Resolves to the method found in [InitializeButtonsFingerprint].
+ */
internal object PivotBarEnumFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_STATIC,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
similarity index 94%
rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt
rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
index e333acb78a..7df2a4ab1c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
@@ -1,4 +1,4 @@
-package app.revanced.patches.youtube.layout.buttons.navigation.utils
+package app.revanced.patches.youtube.misc.navigation.utils
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
From 53684573be810c040a1cac35e5725b8fcc4bedd3 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sun, 17 Mar 2024 19:09:28 +0400
Subject: [PATCH 13/26] Adjust setting strings
---
src/main/resources/addresources/values/strings.xml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index f9b51073ff..0046ce95c4 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -169,21 +169,21 @@
List of component path builder strings to filter separated by new line
Invalid custom filter: %s
Hide keyword content
- Hide feed and search result videos using keyword filters
+ Hide search and feed videos using keyword filters
+ Hide search results by keywordsx
+ Search results are filtered by keywords
+ Search results are not filtered by keywords
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 keywordsx
Videos in the subscriptions tab are filtered by keywords
Videos in the subscriptions tab are not filtered by keywords
- Hide search results by keywordsx
- 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\n\nWords 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\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI elements may not be hidden\n• Searching for a keyword may show no results
- Invalid keyword length (must be at least %s characters): %s
+ Search/Home/Subscription results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results
+ Invalid keyword (must be at least %s characters): %s
Hide general ads
From 83545b4b9d434c5375d5c7b0a9e4d5068dda4e7e Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sun, 17 Mar 2024 19:16:07 +0400
Subject: [PATCH 14/26] refactor: Use existing class name
---
.../youtube/layout/buttons/navigation/NavigationButtonsPatch.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index fd948d35fe..6d8844b7ba 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -57,7 +57,7 @@ object NavigationButtonsPatch : BytecodePatch(
setOf(AddCreateButtonViewFingerprint),
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
- "Lapp/revanced/integrations/youtube/patches/HideNavigationButtonsPatch;"
+ "Lapp/revanced/integrations/youtube/patches/NavigationButtonsPatch;"
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
From 75220accf25fb6750a8636b96be0603bbcae625e Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sun, 17 Mar 2024 19:39:17 +0400
Subject: [PATCH 15/26] refactor: Simplify
---
.../hide/general/HideLayoutComponentsPatch.kt | 19 ++++----
.../misc/navigation/NavigationBarHookPatch.kt | 44 ++++++++-----------
.../NavigationBarHookResourcePatch.kt | 4 +-
3 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index 487c88ad92..f272111763 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -17,14 +17,14 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
-import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
+import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
-import app.revanced.util.exception
+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.TwoRegisterInstruction
@@ -162,15 +162,14 @@ object HideLayoutComponentsPatch : BytecodePatch(
// region Mix playlists
- ParseElementFromBufferFingerprint.result?.let { result ->
- val returnEmptyComponentInstruction =
- result.mutableMethod.getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
+ ParseElementFromBufferFingerprint.resultOrThrow().let { result ->
+ val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
result.mutableMethod.apply {
- val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
val conversionContextRegister =
getInstruction(consumeByteBufferIndex - 2).registerA
val byteBufferRegister = getInstruction(consumeByteBufferIndex).registerD
+ val returnEmptyComponentInstruction = getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
addInstructionsWithLabels(
consumeByteBufferIndex,
@@ -182,15 +181,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
)
}
- } ?: throw ParseElementFromBufferFingerprint.exception
+ }
// endregion
// region Watermark (legacy code for old versions of YouTube)
ShowWatermarkFingerprint.also {
- it.resolve(context, PlayerOverlayFingerprint.result?.classDef ?: throw PlayerOverlayFingerprint.exception)
- }.result?.mutableMethod?.apply {
+ it.resolve(context, PlayerOverlayFingerprint.resultOrThrow().classDef)
+ }.resultOrThrow().mutableMethod.apply {
val index = implementation!!.instructions.size - 5
removeInstruction(index)
@@ -201,7 +200,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
move-result p2
""",
)
- } ?: throw ShowWatermarkFingerprint.exception
+ }
// endregion
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 0bce6d4ce8..3d4f917b27 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -16,8 +16,8 @@ import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarCreateB
import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarEnumFingerprint
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHook
-import app.revanced.util.exception
import app.revanced.util.getReference
+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.reference.MethodReference
@@ -46,29 +46,25 @@ object NavigationBarHookPatch : BytecodePatch(
private lateinit var navigationTabCreatedCallbackMethod: MutableMethod
override fun execute(context: BytecodeContext) {
- PivotBarConstructorFingerprint.result?.let {
+ PivotBarConstructorFingerprint.resultOrThrow().let {
InitializeButtonsFingerprint.resolve(
context,
it.classDef
)
- } ?: throw PivotBarConstructorFingerprint.exception
+ }
- val initializeButtonsResult = InitializeButtonsFingerprint.result
- ?: throw InitializeButtonsFingerprint.exception
+ val initializeButtonsResult = InitializeButtonsFingerprint.resultOrThrow()
val fingerprintResults =
arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint)
.onEach {
- if (!it.resolve(
- context,
- initializeButtonsResult.mutableMethod,
- initializeButtonsResult.mutableClass,
- )
- ) {
- throw it.exception
- }
+ it.resolve(
+ context,
+ initializeButtonsResult.mutableMethod,
+ initializeButtonsResult.mutableClass,
+ )
}
- .map { it.result!!.scanResult.patternScanResult!! }
+ .map { it.resultOrThrow().scanResult.patternScanResult!! }
val enumScanResult = fingerprintResults[0]
val buttonViewResult = fingerprintResults[1]
@@ -93,31 +89,29 @@ object NavigationBarHookPatch : BytecodePatch(
initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
}
- InitializeButtonsFingerprint.result?.let {
- if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) {
- throw PivotBarCreateButtonViewFingerprint.exception
- }
- } ?: throw InitializeButtonsFingerprint.exception
+ InitializeButtonsFingerprint.resultOrThrow().let {
+ PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)
+ }
/**
* Unique hook just for the Create tab button.
*/
- PivotBarCreateButtonViewFingerprint.result?.apply {
+ PivotBarCreateButtonViewFingerprint.resultOrThrow().apply {
val insertIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.injectHook(
insertIndex,
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
)
- } ?: PivotBarCreateButtonViewFingerprint.exception
+ }
/**
* Callback for other patches.
*/
- NavigationBarHookCallbackFingerprint.result?.apply {
+ NavigationBarHookCallbackFingerprint.resultOrThrow().apply {
navigationTabCreatedCallbackMethod = mutableMethod
- } ?: NavigationBarHookCallbackFingerprint.exception
+ }
/**
@@ -127,7 +121,7 @@ object NavigationBarHookPatch : BytecodePatch(
// 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.result?.mutableMethod?.apply {
+ ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
val instructionIndex = implementation!!.instructions.indexOfFirst {
it.opcode == Opcode.INVOKE_VIRTUAL &&
it.getReference()?.name == "setLayoutDirection"
@@ -138,7 +132,7 @@ object NavigationBarHookPatch : BytecodePatch(
"invoke-static { v$register }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V"
)
- } ?: ActionBarSearchResultsFingerprint.exception
+ }
}
fun hookNavigationButtonCreated(classDescriptor: String) {
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
index fc515fd359..3841f2bfaa 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt
@@ -13,11 +13,11 @@ internal object NavigationBarHookResourcePatch : ResourcePatch() {
internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: ResourceContext) {
- imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.single {
+ imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "image_only_tab"
}.id
- actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.single {
+ actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
}.id
}
From 05c03f3a583fe429082a06240976cfa5cb756d27 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Tue, 19 Mar 2024 11:03:01 +0400
Subject: [PATCH 16/26] refactor: Cleanup
---
.../youtube/misc/navigation/NavigationBarHookPatch.kt | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 3d4f917b27..aab31e4f6f 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -89,13 +89,16 @@ object NavigationBarHookPatch : BytecodePatch(
initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
}
- InitializeButtonsFingerprint.resultOrThrow().let {
- PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)
- }
/**
* Unique hook just for the Create tab button.
*/
+ PivotBarCreateButtonViewFingerprint.resolve(
+ context,
+ initializeButtonsResult.mutableMethod,
+ initializeButtonsResult.mutableClass
+ )
+
PivotBarCreateButtonViewFingerprint.resultOrThrow().apply {
val insertIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.injectHook(
From b8aa8eacb084b53f0427456054b6d841325a5064 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Tue, 19 Mar 2024 20:03:24 +0400
Subject: [PATCH 17/26] fix: Detect some keywords that will always hide all
videos
---
src/main/resources/addresources/values/strings.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index 0046ce95c4..e4e786cf0a 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -183,6 +183,7 @@
Keywords and phrases to hide, separated by new lines\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)
About keyword filtering
Search/Home/Subscription results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results
+ Invalid keyword. Cannot use: \'%s\' as a filter
Invalid keyword (must be at least %s characters): %s
From 2094b9df18f300eddc7b3b809d8bfa1dd89f9fb4 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Thu, 21 Mar 2024 12:10:32 +0400
Subject: [PATCH 18/26] fix: Adjust settings text
---
.../layout/hide/general/HideLayoutComponentsPatch.kt | 2 +-
src/main/resources/addresources/values/strings.xml | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index f272111763..9e5e8cfb6d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -129,9 +129,9 @@ object HideLayoutComponentsPatch : BytecodePatch(
key = "revanced_hide_keyword_content_screen",
sorting = Sorting.UNSORTED,
preferences = setOf(
- SwitchPreference("revanced_hide_keyword_content_search"),
SwitchPreference("revanced_hide_keyword_content_home"),
SwitchPreference("revanced_hide_keyword_content_subscriptions"),
+ SwitchPreference("revanced_hide_keyword_content_search"),
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
NonInteractivePreference("revanced_hide_keyword_content_about")
)
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index e4e786cf0a..de5435df50 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -170,21 +170,21 @@
Invalid custom filter: %s
Hide keyword content
Hide search and feed videos using keyword filters
- Hide search results by keywordsx
- Search results are filtered by keywords
- Search results are not filtered by keywords
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 keywordsx
Videos in the subscriptions tab are filtered by keywords
Videos in the subscriptions tab are not filtered by keywords
+ Hide search results by keywordsx
+ 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\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)
About keyword filtering
- Search/Home/Subscription results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results
+ Home/Subscription/Search results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results
Invalid keyword. Cannot use: \'%s\' as a filter
- Invalid keyword (must be at least %s characters): %s
+ Invalid keyword. \'%s\' is less than %s characters
Hide general ads
From 0de51bf9659b94075ab1c09b6a0d219158eb3c8a Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Thu, 21 Mar 2024 15:56:10 +0400
Subject: [PATCH 19/26] fix: Hook the 'You' library tab
---
.../misc/navigation/NavigationBarHookPatch.kt | 103 ++++++++----------
.../YouNavigationTabFingerprint.kt | 16 +++
.../misc/navigation/utils/InjectionUtils.kt | 11 +-
.../resources/addresources/values/strings.xml | 2 +-
4 files changed, 66 insertions(+), 66 deletions(-)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index aab31e4f6f..ab90c6d48f 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -3,6 +3,7 @@ package app.revanced.patches.youtube.misc.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.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -14,6 +15,7 @@ import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtons
import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarConstructorFingerprint
import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarCreateButtonViewFingerprint
import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarEnumFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.YouNavigationTabFingerprint
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHook
import app.revanced.util.getReference
@@ -33,8 +35,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object NavigationBarHookPatch : BytecodePatch(
setOf(
PivotBarConstructorFingerprint,
- ActionBarSearchResultsFingerprint,
- NavigationBarHookCallbackFingerprint
+ NavigationBarHookCallbackFingerprint,
+ ActionBarSearchResultsFingerprint
)
) {
internal const val INTEGRATIONS_CLASS_DESCRIPTOR =
@@ -46,69 +48,55 @@ object NavigationBarHookPatch : BytecodePatch(
private lateinit var navigationTabCreatedCallbackMethod: MutableMethod
override fun execute(context: BytecodeContext) {
- PivotBarConstructorFingerprint.resultOrThrow().let {
- InitializeButtonsFingerprint.resolve(
- context,
- it.classDef
- )
- }
-
- val initializeButtonsResult = InitializeButtonsFingerprint.resultOrThrow()
-
- val fingerprintResults =
- arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint)
- .onEach {
- it.resolve(
- context,
- initializeButtonsResult.mutableMethod,
- initializeButtonsResult.mutableClass,
- )
- }
- .map { it.resultOrThrow().scanResult.patternScanResult!! }
-
- val enumScanResult = fingerprintResults[0]
- val buttonViewResult = fingerprintResults[1]
-
- val enumHookInsertIndex = enumScanResult.startIndex + 2
- val buttonHookInsertIndex = buttonViewResult.endIndex
+ InitializeButtonsFingerprint.resolve(
+ context,
+ PivotBarConstructorFingerprint.resultOrThrow().classDef
+ )
- /*
- * Inject hooks
- */
+ fun MethodFingerprint.patternScanResult() = resultOrThrow().scanResult.patternScanResult!!
- val enumHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
- val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
+ // All of these hooks can be found by filtering the method for the calls to PivotBar
+ // and calls to lookup the Navigation enum.
+ // But the 'You' tab does not have an enum and that approach makes this patch a bit more complicated.
+ InitializeButtonsFingerprint.resultOrThrow().apply {
- // Inject bottom to top to not mess up the indices
- mapOf(
- buttonHook to buttonHookInsertIndex,
- enumHook to enumHookInsertIndex,
- ).forEach { (hook, insertIndex) ->
- initializeButtonsResult.mutableMethod.injectHook(insertIndex, hook)
- }
+ PivotBarEnumFingerprint.also {
+ it.resolve(context, mutableMethod, mutableClass)
+ mutableMethod.injectHook(
+ it.patternScanResult().startIndex + 2,
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
+ )
+ }
+ PivotBarButtonsViewFingerprint.also {
+ it.resolve(context, mutableMethod, mutableClass)
+ mutableMethod.injectHook(
+ it.patternScanResult().endIndex,
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
+ )
+ }
- /**
- * Unique hook just for the Create tab button.
- */
- PivotBarCreateButtonViewFingerprint.resolve(
- context,
- initializeButtonsResult.mutableMethod,
- initializeButtonsResult.mutableClass
- )
+ YouNavigationTabFingerprint.also {
+ it.resolve(context, mutableMethod, mutableClass)
+ mutableMethod.injectHook(
+ it.patternScanResult().startIndex + 3,
+ "invoke-static/range { v$REGISTER_TEMPLATE_REPLACEMENT .. v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->youTabLoaded(Landroid/view/View;)V"
+ )
+ }
- PivotBarCreateButtonViewFingerprint.resultOrThrow().apply {
- val insertIndex = scanResult.patternScanResult!!.endIndex
- mutableMethod.injectHook(
- insertIndex,
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
- )
+ PivotBarCreateButtonViewFingerprint.also {
+ it.resolve(context, mutableMethod, mutableClass)
+ mutableMethod.injectHook(
+ it.patternScanResult().endIndex,
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
+ )
+ }
}
-
/**
* Callback for other patches.
*/
@@ -116,7 +104,6 @@ object NavigationBarHookPatch : BytecodePatch(
navigationTabCreatedCallbackMethod = mutableMethod
}
-
/**
* Search bar.
*/
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
new file mode 100644
index 0000000000..0ceab8e9dc
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
@@ -0,0 +1,16 @@
+package app.revanced.patches.youtube.misc.navigation.fingerprints
+
+import app.revanced.patcher.fingerprint.MethodFingerprint
+import com.android.tools.smali.dexlib2.Opcode
+
+/**
+ * Resolves to the method found in [InitializeButtonsFingerprint].
+ */
+internal object YouNavigationTabFingerprint : MethodFingerprint(
+ opcodes = listOf(
+ Opcode.INVOKE_DIRECT_RANGE,
+ Opcode.INVOKE_VIRTUAL,
+ Opcode.MOVE_RESULT_OBJECT, // target reference
+ Opcode.GOTO_16
+ )
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
index 7df2a4ab1c..92ff564c8d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
@@ -3,7 +3,6 @@ package app.revanced.patches.youtube.misc.navigation.utils
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
-import com.android.tools.smali.dexlib2.Opcode.MOVE_RESULT_OBJECT
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal object InjectionUtils {
@@ -13,18 +12,16 @@ internal object InjectionUtils {
* 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].
+ * a [OneRegisterInstruction] must be present before [insertIndex].
*/
fun MutableMethod.injectHook(insertIndex: Int, hook: String) {
- 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
+ val register = getInstruction(registerIndex).registerA
- injectTarget.addInstruction(
+ addInstruction(
insertIndex,
- hook.replace("REGISTER_INDEX", register.toString()),
+ hook.replace("REGISTER_INDEX", register.toString())
)
}
}
\ No newline at end of file
diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml
index de5435df50..d3eb75b29c 100644
--- a/src/main/resources/addresources/values/strings.xml
+++ b/src/main/resources/addresources/values/strings.xml
@@ -176,7 +176,7 @@
Hide subscription videos by keywordsx
Videos in the subscriptions tab are filtered by keywords
Videos in the subscriptions tab are not filtered by keywords
- Hide search results by keywordsx
+ Hide search results by keywords
Search results are filtered by keywords
Search results are not filtered by keywords
Keywords to hide
From 1db7ddb20fc27efb85e5030f5efee6f4379ce67f Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sun, 24 Mar 2024 19:27:33 +0400
Subject: [PATCH 20/26] refactor: No fingerprint opcodes. Changes needed for
future YT 19.10 support.
---
.../misc/navigation/NavigationBarHookPatch.kt | 83 +++++++++----------
.../fingerprints/NavigationEnumFingerprint.kt | 21 +++++
...BarButtonsCreateDrawableViewFingerprint.kt | 17 ++++
...BarButtonsCreateResourceViewFingerprint.kt | 14 ++++
.../PivotBarButtonsViewFingerprint.kt | 15 ----
.../PivotBarCreateButtonViewFingerprint.kt | 16 ----
.../fingerprints/PivotBarEnumFingerprint.kt | 18 ----
.../YouNavigationTabFingerprint.kt | 16 ----
.../misc/navigation/utils/InjectionUtils.kt | 23 +++++
9 files changed, 114 insertions(+), 109 deletions(-)
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt
create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index ab90c6d48f..bfe1d8fb6c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -3,7 +3,6 @@ package app.revanced.patches.youtube.misc.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.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -11,13 +10,12 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.navigation.fingerprints.ActionBarSearchResultsFingerprint
import app.revanced.patches.youtube.misc.navigation.fingerprints.InitializeButtonsFingerprint
import app.revanced.patches.youtube.misc.navigation.fingerprints.NavigationBarHookCallbackFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsViewFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.NavigationEnumFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsCreateDrawableViewFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsCreateResourceViewFingerprint
import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarConstructorFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarCreateButtonViewFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarEnumFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.YouNavigationTabFingerprint
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
-import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHook
+import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHooksByFilter
import app.revanced.util.getReference
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
@@ -35,6 +33,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object NavigationBarHookPatch : BytecodePatch(
setOf(
PivotBarConstructorFingerprint,
+ NavigationEnumFingerprint,
+ PivotBarButtonsCreateDrawableViewFingerprint,
+ PivotBarButtonsCreateResourceViewFingerprint,
NavigationBarHookCallbackFingerprint,
ActionBarSearchResultsFingerprint
)
@@ -53,48 +54,42 @@ object NavigationBarHookPatch : BytecodePatch(
PivotBarConstructorFingerprint.resultOrThrow().classDef
)
- fun MethodFingerprint.patternScanResult() = resultOrThrow().scanResult.patternScanResult!!
-
- // All of these hooks can be found by filtering the method for the calls to PivotBar
- // and calls to lookup the Navigation enum.
- // But the 'You' tab does not have an enum and that approach makes this patch a bit more complicated.
InitializeButtonsFingerprint.resultOrThrow().apply {
- PivotBarEnumFingerprint.also {
- it.resolve(context, mutableMethod, mutableClass)
- mutableMethod.injectHook(
- it.patternScanResult().startIndex + 2,
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
- )
- }
-
- PivotBarButtonsViewFingerprint.also {
- it.resolve(context, mutableMethod, mutableClass)
- mutableMethod.injectHook(
- it.patternScanResult().endIndex,
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
- )
- }
+ // Hook the navigation enum. Note: The 'You' tab does not have an enum hook.
+ val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type
+ mutableMethod.injectHooksByFilter(
+ {
+ it.opcode == Opcode.INVOKE_STATIC &&
+ it.getReference()?.definingClass == navigationEnumClassName
+ },
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
+ )
- YouNavigationTabFingerprint.also {
- it.resolve(context, mutableMethod, mutableClass)
- mutableMethod.injectHook(
- it.patternScanResult().startIndex + 3,
- "invoke-static/range { v$REGISTER_TEMPLATE_REPLACEMENT .. v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->youTabLoaded(Landroid/view/View;)V"
- )
- }
+ // Hook the creation of navigation tab views.
+ val drawableTabResult = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow()
+ mutableMethod.injectHooksByFilter(
+ {
+ // Don't need to check for the opcode since the method reference already validates.
+ val reference = it.getReference()
+ reference?.definingClass == drawableTabResult.mutableClass.type &&
+ reference.name == drawableTabResult.mutableMethod.name
+ },
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
+ )
- PivotBarCreateButtonViewFingerprint.also {
- it.resolve(context, mutableMethod, mutableClass)
- mutableMethod.injectHook(
- it.patternScanResult().endIndex,
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->createTabLoaded(Landroid/view/View;)V"
- )
- }
+ val imageResourceTabResult = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow()
+ mutableMethod.injectHooksByFilter(
+ {
+ val reference = it.getReference()
+ reference?.definingClass == imageResourceTabResult.mutableClass.type &&
+ reference.name == imageResourceTabResult.mutableMethod.name
+ },
+ "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationImageResourceTabLoaded(Landroid/view/View;)V"
+ )
}
/**
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt
new file mode 100644
index 0000000000..c084cf5ec1
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt
@@ -0,0 +1,21 @@
+package app.revanced.patches.youtube.misc.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/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt
new file mode 100644
index 0000000000..0192f6e3d4
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt
@@ -0,0 +1,17 @@
+package app.revanced.patches.youtube.misc.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/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt
new file mode 100644
index 0000000000..cef0b517eb
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt
@@ -0,0 +1,14 @@
+package app.revanced.patches.youtube.misc.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/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
deleted file mode 100644
index cb8328dff8..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package app.revanced.patches.youtube.misc.navigation.fingerprints
-
-import app.revanced.patcher.fingerprint.MethodFingerprint
-import com.android.tools.smali.dexlib2.Opcode
-
-/**
- * Resolves to the method found in [InitializeButtonsFingerprint].
- */
-internal object PivotBarButtonsViewFingerprint : MethodFingerprint(
- opcodes = listOf(
- Opcode.INVOKE_VIRTUAL_RANGE,
- Opcode.MOVE_RESULT_OBJECT, // target reference
- Opcode.GOTO,
- )
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
deleted file mode 100644
index f438eea73e..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package app.revanced.patches.youtube.misc.navigation.fingerprints
-
-import app.revanced.patcher.fingerprint.MethodFingerprint
-import com.android.tools.smali.dexlib2.Opcode
-
-/**
- * Resolves to the method found in [InitializeButtonsFingerprint].
- */
-internal object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
- opcodes = listOf(
- Opcode.INVOKE_DIRECT_RANGE,
- Opcode.INVOKE_VIRTUAL,
- Opcode.MOVE_RESULT_OBJECT,
- Opcode.INVOKE_STATIC
- )
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
deleted file mode 100644
index 864873aa70..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarEnumFingerprint.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package app.revanced.patches.youtube.misc.navigation.fingerprints
-
-import app.revanced.patcher.fingerprint.MethodFingerprint
-import com.android.tools.smali.dexlib2.Opcode
-
-/**
- * Resolves to the method found in [InitializeButtonsFingerprint].
- */
-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/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
deleted file mode 100644
index 0ceab8e9dc..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/YouNavigationTabFingerprint.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package app.revanced.patches.youtube.misc.navigation.fingerprints
-
-import app.revanced.patcher.fingerprint.MethodFingerprint
-import com.android.tools.smali.dexlib2.Opcode
-
-/**
- * Resolves to the method found in [InitializeButtonsFingerprint].
- */
-internal object YouNavigationTabFingerprint : MethodFingerprint(
- opcodes = listOf(
- Opcode.INVOKE_DIRECT_RANGE,
- Opcode.INVOKE_VIRTUAL,
- Opcode.MOVE_RESULT_OBJECT, // target reference
- Opcode.GOTO_16
- )
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
index 92ff564c8d..dddd02b5bf 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
@@ -2,7 +2,9 @@ package app.revanced.patches.youtube.misc.navigation.utils
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
+import com.android.tools.smali.dexlib2.builder.BuilderInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal object InjectionUtils {
@@ -24,4 +26,25 @@ internal object InjectionUtils {
hook.replace("REGISTER_INDEX", register.toString())
)
}
+
+ /**
+ * @param insertionFilter Filter that identifies method calls with a non void return type.
+ */
+ fun MutableMethod.injectHooksByFilter(
+ insertionFilter: (BuilderInstruction) -> Boolean,
+ hook: String
+ ) {
+ val methodInstructions = implementation!!.instructions
+ methodInstructions.filter(insertionFilter).let { filteredInstructions ->
+ if (filteredInstructions.isEmpty()) throw PatchException("Could not find insertion indexes")
+ filteredInstructions.forEach {
+ val index = methodInstructions.indexOf(it)
+ val register = (getInstruction(index + 1) as OneRegisterInstruction).registerA
+ addInstruction(
+ index + 2,
+ hook.replace("REGISTER_INDEX", register.toString()),
+ )
+ }
+ }
+ }
}
\ No newline at end of file
From 001d210a7071d697017484833136649911aca69c Mon Sep 17 00:00:00 2001
From: oSumAtrIX
Date: Tue, 26 Mar 2024 19:22:06 +0100
Subject: [PATCH 21/26] adjust description
---
.../misc/navigation/NavigationBarHookPatch.kt | 39 ++++++++-----------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index bfe1d8fb6c..684662df67 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -7,13 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
-import app.revanced.patches.youtube.misc.navigation.fingerprints.ActionBarSearchResultsFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.InitializeButtonsFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.NavigationBarHookCallbackFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.NavigationEnumFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsCreateDrawableViewFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarButtonsCreateResourceViewFingerprint
-import app.revanced.patches.youtube.misc.navigation.fingerprints.PivotBarConstructorFingerprint
+import app.revanced.patches.youtube.misc.navigation.fingerprints.*
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHooksByFilter
import app.revanced.util.getReference
@@ -23,11 +17,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
- description = "Hook to get the current navigation bar tab that is active, and if the search bar is active.",
+ description = "Hooks the active navigation or search bar.",
dependencies = [
IntegrationsPatch::class,
- NavigationBarHookResourcePatch::class
- ]
+ NavigationBarHookResourcePatch::class,
+ ],
)
@Suppress("unused")
object NavigationBarHookPatch : BytecodePatch(
@@ -37,8 +31,8 @@ object NavigationBarHookPatch : BytecodePatch(
PivotBarButtonsCreateDrawableViewFingerprint,
PivotBarButtonsCreateResourceViewFingerprint,
NavigationBarHookCallbackFingerprint,
- ActionBarSearchResultsFingerprint
- )
+ ActionBarSearchResultsFingerprint,
+ ),
) {
internal const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/shared/NavigationBar;"
@@ -51,20 +45,19 @@ object NavigationBarHookPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
InitializeButtonsFingerprint.resolve(
context,
- PivotBarConstructorFingerprint.resultOrThrow().classDef
+ PivotBarConstructorFingerprint.resultOrThrow().classDef,
)
InitializeButtonsFingerprint.resultOrThrow().apply {
-
// Hook the navigation enum. Note: The 'You' tab does not have an enum hook.
val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type
mutableMethod.injectHooksByFilter(
{
it.opcode == Opcode.INVOKE_STATIC &&
- it.getReference()?.definingClass == navigationEnumClassName
+ it.getReference()?.definingClass == navigationEnumClassName
},
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V",
)
// Hook the creation of navigation tab views.
@@ -74,10 +67,10 @@ object NavigationBarHookPatch : BytecodePatch(
// Don't need to check for the opcode since the method reference already validates.
val reference = it.getReference()
reference?.definingClass == drawableTabResult.mutableClass.type &&
- reference.name == drawableTabResult.mutableMethod.name
+ reference.name == drawableTabResult.mutableMethod.name
},
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V"
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V",
)
val imageResourceTabResult = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow()
@@ -85,10 +78,10 @@ object NavigationBarHookPatch : BytecodePatch(
{
val reference = it.getReference()
reference?.definingClass == imageResourceTabResult.mutableClass.type &&
- reference.name == imageResourceTabResult.mutableMethod.name
+ reference.name == imageResourceTabResult.mutableMethod.name
},
"invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationImageResourceTabLoaded(Landroid/view/View;)V"
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationImageResourceTabLoaded(Landroid/view/View;)V",
)
}
@@ -109,13 +102,13 @@ object NavigationBarHookPatch : BytecodePatch(
ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
val instructionIndex = implementation!!.instructions.indexOfFirst {
it.opcode == Opcode.INVOKE_VIRTUAL &&
- it.getReference()?.name == "setLayoutDirection"
+ it.getReference()?.name == "setLayoutDirection"
}
val register = getInstruction(instructionIndex).registerC
addInstruction(
instructionIndex,
"invoke-static { v$register }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V"
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V",
)
}
}
@@ -124,7 +117,7 @@ object NavigationBarHookPatch : BytecodePatch(
navigationTabCreatedCallbackMethod.addInstruction(
0,
"invoke-static { p0, p1 }, " +
- "$classDescriptor->navigationTabCreated(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V"
+ "$classDescriptor->navigationTabCreated(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
)
}
}
From c7d18e27d857e378f1cd6095e052f3f004d4b101 Mon Sep 17 00:00:00 2001
From: oSumAtrIX
Date: Tue, 26 Mar 2024 20:01:07 +0100
Subject: [PATCH 22/26] refactor
---
api/revanced-patches.api | 2 +-
.../navigation/NavigationButtonsPatch.kt | 10 +-
.../misc/navigation/NavigationBarHookPatch.kt | 121 +++++++++---------
.../NavigationBarHookCallbackFingerprint.kt | 13 +-
.../misc/navigation/utils/InjectionUtils.kt | 7 +-
5 files changed, 74 insertions(+), 79 deletions(-)
diff --git a/api/revanced-patches.api b/api/revanced-patches.api
index 7de20cba64..521de80996 100644
--- a/api/revanced-patches.api
+++ b/api/revanced-patches.api
@@ -1613,7 +1613,7 @@ public final class app/revanced/patches/youtube/misc/navigation/NavigationBarHoo
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
- public final fun hookNavigationButtonCreated (Ljava/lang/String;)V
+ public final fun getHookNavigationButtonCreated ()Lkotlin/jvm/functions/Function1;
}
public final class app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable {
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index 6d8844b7ba..c660344deb 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -25,7 +25,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
IntegrationsPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
- NavigationBarHookPatch::class
+ NavigationBarHookPatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -47,7 +47,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
- "19.09.37"
+ "19.09.37",
],
),
],
@@ -76,10 +76,7 @@ object NavigationButtonsPatch : BytecodePatch(
),
)
- /*
- * Switch create button with notification.
- */
-
+ // Switch create with notifications button.
AddCreateButtonViewFingerprint.result?.let {
it.mutableMethod.apply {
val stringIndex = it.scanResult.stringsScanResult!!.matches.find { match ->
@@ -100,6 +97,7 @@ object NavigationButtonsPatch : BytecodePatch(
}
} ?: throw AddCreateButtonViewFingerprint.exception
+ // Hook navigation button created, in order to hide them.
NavigationBarHookPatch.hookNavigationButtonCreated(INTEGRATIONS_CLASS_DESCRIPTOR)
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 684662df67..19c7a8dadf 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -3,18 +3,21 @@ package app.revanced.patches.youtube.misc.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.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.navigation.fingerprints.*
-import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
-import app.revanced.patches.youtube.misc.navigation.utils.InjectionUtils.injectHooksByFilter
import app.revanced.util.getReference
+import app.revanced.util.indexOfFirstInstruction
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.",
@@ -40,84 +43,82 @@ object NavigationBarHookPatch : BytecodePatch(
internal const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/shared/NavigationBar\$NavigationButton;"
- private lateinit var navigationTabCreatedCallbackMethod: MutableMethod
-
override fun execute(context: BytecodeContext) {
- InitializeButtonsFingerprint.resolve(
- context,
- PivotBarConstructorFingerprint.resultOrThrow().classDef,
- )
+ fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) =
+ getInstructions().filter(insertPredicate).forEach {
+ val register = (getInstruction(it.location.index + 1) as OneRegisterInstruction).registerA
+
+ addInstruction(
+ it.location.index + 2,
+ "invoke-static { v$register }, " +
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V",
+ )
+ }
- InitializeButtonsFingerprint.resultOrThrow().apply {
- // Hook the navigation enum. Note: The 'You' tab does not have an enum hook.
+ InitializeButtonsFingerprint.resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
+ InitializeButtonsFingerprint.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
- mutableMethod.injectHooksByFilter(
- {
- it.opcode == Opcode.INVOKE_STATIC &&
- it.getReference()?.definingClass == navigationEnumClassName
- },
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V",
- )
+ addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) {
+ opcode == Opcode.INVOKE_STATIC &&
+ getReference()?.definingClass == navigationEnumClassName
+ }
// Hook the creation of navigation tab views.
- val drawableTabResult = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow()
- mutableMethod.injectHooksByFilter(
- {
- // Don't need to check for the opcode since the method reference already validates.
- val reference = it.getReference()
- reference?.definingClass == drawableTabResult.mutableClass.type &&
- reference.name == drawableTabResult.mutableMethod.name
- },
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationTabLoaded(Landroid/view/View;)V",
- )
-
- val imageResourceTabResult = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow()
- mutableMethod.injectHooksByFilter(
- {
- val reference = it.getReference()
- reference?.definingClass == imageResourceTabResult.mutableClass.type &&
- reference.name == imageResourceTabResult.mutableMethod.name
- },
- "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
- "$INTEGRATIONS_CLASS_DESCRIPTOR->navigationImageResourceTabLoaded(Landroid/view/View;)V",
- )
- }
+ val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
+ addHook(Hook.NAVIGATION_TAB_LOADED) {
+ MethodUtil.methodSignaturesMatch(
+ getReference() ?: return@addHook false,
+ drawableTabMethod,
+ )
+ }
- /**
- * Callback for other patches.
- */
- NavigationBarHookCallbackFingerprint.resultOrThrow().apply {
- navigationTabCreatedCallbackMethod = mutableMethod
+ val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
+ addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) {
+ MethodUtil.methodSignaturesMatch(
+ getReference() ?: return@addHook false,
+ imageResourceTabMethod,
+ )
+ }
}
- /**
- * Search bar.
- */
+ // 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 = implementation!!.instructions.indexOfFirst {
- it.opcode == Opcode.INVOKE_VIRTUAL &&
- it.getReference()?.name == "setLayoutDirection"
+ val instructionIndex = indexOfFirstInstruction {
+ opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setLayoutDirection"
}
- val register = getInstruction(instructionIndex).registerC
+
+ val viewRegister = getInstruction(instructionIndex).registerC
+
addInstruction(
instructionIndex,
- "invoke-static { v$register }, " +
+ "invoke-static { v$viewRegister }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V",
)
}
}
- fun hookNavigationButtonCreated(classDescriptor: String) {
- navigationTabCreatedCallbackMethod.addInstruction(
- 0,
- "invoke-static { p0, p1 }, " +
- "$classDescriptor->navigationTabCreated(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
- )
+ val hookNavigationButtonCreated: (String) -> Unit by lazy {
+ val method = NavigationBarHookCallbackFingerprint.resultOrThrow().mutableMethod
+
+ { integrationsClassDescriptor ->
+ method.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;"),
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
index 6cc2f8aa3b..1d69dfe893 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt
@@ -13,12 +13,9 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object NavigationBarHookCallbackFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "V",
- parameters = listOf(
- NavigationBarHookPatch.INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR,
- "Landroid/view/View;"
- ),
+ parameters = listOf(NavigationBarHookPatch.INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR, "Landroid/view/View;"),
customFingerprint = { methodDef, _ ->
- methodDef.name == "navigationTabCreatedCallback"
- && methodDef.definingClass == NavigationBarHookPatch.INTEGRATIONS_CLASS_DESCRIPTOR
- }
-)
\ No newline at end of file
+ methodDef.name == "navigationTabCreatedCallback" &&
+ methodDef.definingClass == NavigationBarHookPatch.INTEGRATIONS_CLASS_DESCRIPTOR
+ },
+)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
index dddd02b5bf..2dd88e948d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
@@ -8,7 +8,6 @@ import com.android.tools.smali.dexlib2.builder.BuilderInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal object InjectionUtils {
- const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX"
/**
* Injects an instruction into insertIndex of the hook.
@@ -23,7 +22,7 @@ internal object InjectionUtils {
addInstruction(
insertIndex,
- hook.replace("REGISTER_INDEX", register.toString())
+ hook.replace("REGISTER_INDEX", register.toString()),
)
}
@@ -32,7 +31,7 @@ internal object InjectionUtils {
*/
fun MutableMethod.injectHooksByFilter(
insertionFilter: (BuilderInstruction) -> Boolean,
- hook: String
+ hook: String,
) {
val methodInstructions = implementation!!.instructions
methodInstructions.filter(insertionFilter).let { filteredInstructions ->
@@ -47,4 +46,4 @@ internal object InjectionUtils {
}
}
}
-}
\ No newline at end of file
+}
From 4a0ce3bfc614943b7e623e4403d8281e348460bc Mon Sep 17 00:00:00 2001
From: oSumAtrIX
Date: Tue, 26 Mar 2024 20:10:24 +0100
Subject: [PATCH 23/26] remove obsolete class
---
.../misc/navigation/utils/InjectionUtils.kt | 49 -------------------
1 file changed, 49 deletions(-)
delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
deleted file mode 100644
index 2dd88e948d..0000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/utils/InjectionUtils.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package app.revanced.patches.youtube.misc.navigation.utils
-
-import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
-import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
-import app.revanced.patcher.patch.PatchException
-import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
-import com.android.tools.smali.dexlib2.builder.BuilderInstruction
-import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
-
-internal object InjectionUtils {
-
- /**
- * Injects an instruction into insertIndex of the hook.
- * @param hook The hook to insert.
- * @param insertIndex The index to insert the instruction at.
- * a [OneRegisterInstruction] must be present before [insertIndex].
- */
- fun MutableMethod.injectHook(insertIndex: Int, hook: String) {
- // Register to pass to the hook
- val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction
- val register = getInstruction(registerIndex).registerA
-
- addInstruction(
- insertIndex,
- hook.replace("REGISTER_INDEX", register.toString()),
- )
- }
-
- /**
- * @param insertionFilter Filter that identifies method calls with a non void return type.
- */
- fun MutableMethod.injectHooksByFilter(
- insertionFilter: (BuilderInstruction) -> Boolean,
- hook: String,
- ) {
- val methodInstructions = implementation!!.instructions
- methodInstructions.filter(insertionFilter).let { filteredInstructions ->
- if (filteredInstructions.isEmpty()) throw PatchException("Could not find insertion indexes")
- filteredInstructions.forEach {
- val index = methodInstructions.indexOf(it)
- val register = (getInstruction(index + 1) as OneRegisterInstruction).registerA
- addInstruction(
- index + 2,
- hook.replace("REGISTER_INDEX", register.toString()),
- )
- }
- }
- }
-}
From 4f11db095405f25369f93755768b834407b7d646 Mon Sep 17 00:00:00 2001
From: oSumAtrIX
Date: Wed, 27 Mar 2024 03:21:56 +0100
Subject: [PATCH 24/26] return to predicate
---
.../youtube/misc/navigation/NavigationBarHookPatch.kt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 19c7a8dadf..2151ed88d9 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -66,17 +66,17 @@ object NavigationBarHookPatch : BytecodePatch(
// Hook the creation of navigation tab views.
val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
- addHook(Hook.NAVIGATION_TAB_LOADED) {
+ addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
MethodUtil.methodSignaturesMatch(
- getReference() ?: return@addHook false,
+ getReference() ?: return@predicate false,
drawableTabMethod,
)
}
val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
- addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) {
+ addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{
MethodUtil.methodSignaturesMatch(
- getReference() ?: return@addHook false,
+ getReference() ?: return@predicate false,
imageResourceTabMethod,
)
}
From 6eae9421cd6c5d1a138be414b1fd0b65a7051c7a Mon Sep 17 00:00:00 2001
From: oSumAtrIX
Date: Wed, 27 Mar 2024 03:22:52 +0100
Subject: [PATCH 25/26] refactor
---
.../youtube/misc/navigation/NavigationBarHookPatch.kt | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 2151ed88d9..675035253f 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -46,17 +46,19 @@ object NavigationBarHookPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) =
getInstructions().filter(insertPredicate).forEach {
- val register = (getInstruction(it.location.index + 1) as OneRegisterInstruction).registerA
+ val insertIndex = it.location.index + 2
+ val register = getInstruction(insertIndex - 1).registerA
addInstruction(
- it.location.index + 2,
+ insertIndex,
"invoke-static { v$register }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V",
)
}
- InitializeButtonsFingerprint.resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
- InitializeButtonsFingerprint.resultOrThrow().mutableMethod.apply {
+ 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) {
From 70d5c7a20d3edd39732f016be009f554324ad479 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Wed, 27 Mar 2024 11:23:52 +0400
Subject: [PATCH 26/26] refactor: Throw an exception if the filter matched
nothing
---
.../youtube/misc/navigation/NavigationBarHookPatch.kt | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 675035253f..5b19cdc0a6 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -5,6 +5,7 @@ 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.misc.integrations.IntegrationsPatch
@@ -44,17 +45,20 @@ object NavigationBarHookPatch : BytecodePatch(
"Lapp/revanced/integrations/youtube/shared/NavigationBar\$NavigationButton;"
override fun execute(context: BytecodeContext) {
- fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) =
- getInstructions().filter(insertPredicate).forEach {
+ 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",
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V",
)
}
+ }
InitializeButtonsFingerprint.apply {
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)