Skip to content

Commit 9bdbbc5

Browse files
committed
YouTube: Add hide navigation buttons
1 parent 73091f6 commit 9bdbbc5

File tree

4 files changed

+204
-15
lines changed

4 files changed

+204
-15
lines changed

app/src/main/java/app/revanced/extension/youtube/shared/NavigationBar.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
/*
2+
* Custom changes: navigationTabCreatedCallback
3+
* */
14
package app.revanced.extension.youtube.shared;
25

36
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE;
7+
import static io.github.chsbuffer.revancedxposed.youtube.misc.NavigationBarHookKt.hookNavigationButtonCreated;
48

59
import android.app.Activity;
610
import android.graphics.drawable.Drawable;
@@ -273,7 +277,8 @@ public static void onBackPressed(Activity activity) {
273277

274278
/** @noinspection EmptyMethod*/
275279
private static void navigationTabCreatedCallback(NavigationButton button, View tabView) {
276-
// Code is added during patching.
280+
// custom change
281+
hookNavigationButtonCreated.forEach(f -> f.invoke(button, tabView));
277282
}
278283

279284
/**
Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,64 @@
11
package io.github.chsbuffer.revancedxposed
22

3+
import org.luckypray.dexkit.DexKitBridge
34
import org.luckypray.dexkit.query.matchers.MethodMatcher
45
import org.luckypray.dexkit.query.matchers.base.OpCodesMatcher
6+
import org.luckypray.dexkit.result.MethodData
7+
import org.luckypray.dexkit.util.DexSignUtil.getTypeName
8+
import java.lang.reflect.Modifier
59

10+
fun DexKitBridge.fingerprint(block: MethodMatcher.() -> Unit): MethodData {
11+
return findMethod {
12+
matcher {
13+
block(this)
14+
}
15+
}.single()
16+
}
617

718
fun MethodMatcher.strings(vararg strings: String) {
819
this.usingStrings(strings.toList())
920
}
1021

1122
fun MethodMatcher.opcodes(vararg opcodes: Opcode): OpCodesMatcher {
1223
return OpCodesMatcher(opcodes.map { it.opCode }).also {
13-
this.opCodes(it)
14-
}
24+
this.opCodes(it)
25+
}
26+
}
27+
28+
enum class AccessFlags(val modifier: Int) {
29+
PUBLIC(Modifier.PUBLIC),
30+
PRIVATE(Modifier.PRIVATE),
31+
PROTECTED(Modifier.PROTECTED),
32+
STATIC(Modifier.STATIC),
33+
FINAL(Modifier.FINAL),
34+
CONSTRUCTOR(0),
35+
}
36+
37+
fun MethodMatcher.accessFlags(vararg accessFlags: AccessFlags) {
38+
this.modifiers(accessFlags.map { it.modifier }.reduce { acc, next -> acc or next })
39+
if (accessFlags.contains(AccessFlags.CONSTRUCTOR)) {
40+
if (accessFlags.contains(AccessFlags.STATIC))
41+
this.name = "<clinit>"
42+
else
43+
this.name = "<init>"
44+
}
45+
}
46+
47+
fun MethodMatcher.parameters(vararg parameters: String) {
48+
this.paramTypes(parameters.map {
49+
if (it.trimStart('[').startsWith('L') && !it.endsWith(';')) null
50+
else getTypeName(it)
51+
})
52+
}
53+
54+
fun MethodMatcher.returns(returnType: String) {
55+
this.returnType = getTypeName(returnType)
56+
}
57+
58+
fun MethodMatcher.definingClass(definingClass: String) {
59+
this.declaredClass = getTypeName(definingClass)
60+
}
61+
62+
fun MethodMatcher.literal(literalSupplier: () -> Number) {
63+
this.usingNumbers(literalSupplier())
1564
}
Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
package io.github.chsbuffer.revancedxposed.youtube.layout
22

3+
import android.widget.TextView
34
import app.revanced.extension.youtube.patches.NavigationButtonsPatch
5+
import io.github.chsbuffer.revancedxposed.AccessFlags
6+
import io.github.chsbuffer.revancedxposed.Opcode
47
import io.github.chsbuffer.revancedxposed.ScopedHook
8+
import io.github.chsbuffer.revancedxposed.accessFlags
9+
import io.github.chsbuffer.revancedxposed.fingerprint
10+
import io.github.chsbuffer.revancedxposed.opcodes
11+
import io.github.chsbuffer.revancedxposed.parameters
12+
import io.github.chsbuffer.revancedxposed.returns
513
import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.PreferenceScreenPreference
614
import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
715
import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.SwitchPreference
816
import io.github.chsbuffer.revancedxposed.strings
917
import io.github.chsbuffer.revancedxposed.youtube.YoutubeHook
18+
import io.github.chsbuffer.revancedxposed.youtube.misc.NavigationBarHook
1019
import io.github.chsbuffer.revancedxposed.youtube.misc.PreferenceScreen
20+
import io.github.chsbuffer.revancedxposed.youtube.misc.hookNavigationButtonCreated
21+
import org.luckypray.dexkit.wrap.DexMethod
1122

1223
fun YoutubeHook.NavigationButtons() {
24+
dependsOn(::NavigationBarHook)
25+
1326
val preferences = mutableSetOf(
14-
// SwitchPreference("revanced_hide_home_button"),
15-
// SwitchPreference("revanced_hide_shorts_button"),
16-
// SwitchPreference("revanced_hide_create_button"),
17-
// SwitchPreference("revanced_hide_subscriptions_button"),
18-
// SwitchPreference("revanced_hide_notifications_button"),
27+
SwitchPreference("revanced_hide_home_button"),
28+
SwitchPreference("revanced_hide_shorts_button"),
29+
SwitchPreference("revanced_hide_create_button"),
30+
SwitchPreference("revanced_hide_subscriptions_button"),
31+
SwitchPreference("revanced_hide_notifications_button"),
1932
SwitchPreference("revanced_switch_create_with_notifications_button"),
20-
// SwitchPreference("revanced_hide_navigation_button_labels"),
33+
SwitchPreference("revanced_hide_navigation_button_labels"),
2134
)
2235

2336
PreferenceScreen.GENERAL_LAYOUT.addPreferences(
@@ -28,6 +41,28 @@ fun YoutubeHook.NavigationButtons() {
2841
)
2942
)
3043

44+
// Hide navigation button labels.
45+
getDexMethod("createPivotBarFingerprint") {
46+
fingerprint {
47+
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
48+
returns("V")
49+
parameters(
50+
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
51+
"Landroid/widget/TextView;",
52+
"Ljava/lang/CharSequence;",
53+
)
54+
opcodes(
55+
Opcode.INVOKE_VIRTUAL,
56+
Opcode.RETURN_VOID,
57+
)
58+
}
59+
}.hookMethod(ScopedHook(DexMethod("Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V").toMethod()) {
60+
before {
61+
NavigationButtonsPatch.hideNavigationButtonLabels(param.thisObject as TextView)
62+
}
63+
})
64+
65+
// Switch create with notifications button.
3166
val ANDROID_AUTOMOTIVE_STRING = "Android Automotive"
3267

3368
getDexMethod("addCreateButtonViewFingerprint") {
@@ -40,10 +75,11 @@ fun YoutubeHook.NavigationButtons() {
4075
}.single()
4176
}
4277
}
43-
}.hookMethod(
44-
ScopedHook(getDexMethod("AutoMotiveFeatureMethod").toMethod()) {
45-
before {
46-
param.result = NavigationButtonsPatch.switchCreateWithNotificationButton()
47-
}
48-
})
78+
}.hookMethod(ScopedHook(getDexMethod("AutoMotiveFeatureMethod").toMethod()) {
79+
before {
80+
param.result = NavigationButtonsPatch.switchCreateWithNotificationButton()
81+
}
82+
})
83+
84+
hookNavigationButtonCreated.add { button, view -> NavigationButtonsPatch.navigationTabCreated(button, view) }
4985
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package io.github.chsbuffer.revancedxposed.youtube.misc
2+
3+
import android.annotation.SuppressLint
4+
import android.view.View
5+
import app.revanced.extension.shared.Utils
6+
import app.revanced.extension.youtube.shared.NavigationBar
7+
import app.revanced.extension.youtube.shared.NavigationBar.NavigationButton
8+
import io.github.chsbuffer.revancedxposed.AccessFlags
9+
import io.github.chsbuffer.revancedxposed.ScopedHook
10+
import io.github.chsbuffer.revancedxposed.accessFlags
11+
import io.github.chsbuffer.revancedxposed.definingClass
12+
import io.github.chsbuffer.revancedxposed.fingerprint
13+
import io.github.chsbuffer.revancedxposed.literal
14+
import io.github.chsbuffer.revancedxposed.parameters
15+
import io.github.chsbuffer.revancedxposed.returns
16+
import io.github.chsbuffer.revancedxposed.strings
17+
import io.github.chsbuffer.revancedxposed.youtube.YoutubeHook
18+
19+
@JvmField
20+
val hookNavigationButtonCreated: MutableList<(NavigationButton, View) -> Unit> = mutableListOf()
21+
22+
@SuppressLint("NonUniqueDexKitData")
23+
fun YoutubeHook.NavigationBarHook() {
24+
25+
val initializeButtonsFingerprint = getDexMethod("initializeButtonsFingerprint") {
26+
val pivotBarConstructorFingerprint = fingerprint {
27+
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
28+
strings("com.google.android.apps.youtube.app.endpoint.flags")
29+
}
30+
31+
val imageOnlyTabResourceId = Utils.getResourceIdentifier("image_only_tab", "layout")
32+
pivotBarConstructorFingerprint.declaredClass!!.findMethod {
33+
matcher {
34+
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
35+
returns("V")
36+
literal { imageOnlyTabResourceId }
37+
}
38+
}.single()
39+
}
40+
// Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value.
41+
val getNavigationEnumMethod = getDexMethod("navigationEnumClass_INVOKE_STATIC") {
42+
val navigationEnumFingerprint = fingerprint {
43+
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
44+
strings(
45+
"PIVOT_HOME",
46+
"TAB_SHORTS",
47+
"CREATION_TAB_LARGE",
48+
"PIVOT_SUBSCRIPTIONS",
49+
"TAB_ACTIVITY",
50+
"VIDEO_LIBRARY_WHITE",
51+
"INCOGNITO_CIRCLE",
52+
)
53+
}
54+
this.getMethodData(initializeButtonsFingerprint.toString())!!.invokes.findMethod {
55+
matcher {
56+
declaredClass(navigationEnumFingerprint.className)
57+
accessFlags(AccessFlags.STATIC)
58+
}
59+
}.single()
60+
}
61+
initializeButtonsFingerprint.hookMethod(ScopedHook(getNavigationEnumMethod.toMethod()) {
62+
after { NavigationBar.setLastAppNavigationEnum(param.result as Enum<*>) }
63+
})
64+
65+
// Hook the creation of navigation tab views.
66+
val pivotBarButtonsCreateDrawableViewFingerprint =
67+
getDexMethod("pivotBarButtonsCreateDrawableViewFingerprint") {
68+
findMethod {
69+
matcher {
70+
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
71+
returns("Landroid/view/View;")
72+
declaredClass {
73+
descriptor =
74+
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
75+
}
76+
}
77+
}.single {
78+
it.paramTypes.firstOrNull()?.descriptor == "Landroid/graphics/drawable/Drawable;"
79+
}
80+
}
81+
82+
initializeButtonsFingerprint.hookMethod(ScopedHook(pivotBarButtonsCreateDrawableViewFingerprint.toMethod()) {
83+
after { NavigationBar.navigationTabLoaded(param.result as View) }
84+
})
85+
86+
val pivotBarButtonsCreateResourceViewFingerprint =
87+
getDexMethod("pivotBarButtonsCreateResourceViewFingerprint") {
88+
fingerprint {
89+
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
90+
returns("Landroid/view/View;")
91+
parameters("L", "Z", "I", "L")
92+
definingClass("Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;")
93+
}
94+
}
95+
96+
initializeButtonsFingerprint.hookMethod(ScopedHook(pivotBarButtonsCreateResourceViewFingerprint.toMethod()) {
97+
after { NavigationBar.navigationImageResourceTabLoaded(param.result as View) }
98+
})
99+
}

0 commit comments

Comments
 (0)