Skip to content

Commit 10ea250

Browse files
fix(YouTube - Custom branding): Use ReVanced icon for status bar notification icon (#6108)
1 parent 5bd0f11 commit 10ea250

File tree

17 files changed

+405
-205
lines changed

17 files changed

+405
-205
lines changed

extensions/music/src/main/java/app/revanced/extension/music/settings/preference/MusicPreferenceFragment.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import android.widget.Toolbar;
66

77
import app.revanced.extension.music.settings.MusicActivityHook;
8+
import app.revanced.extension.shared.GmsCoreSupport;
89
import app.revanced.extension.shared.Logger;
910
import app.revanced.extension.shared.Utils;
11+
import app.revanced.extension.shared.settings.BaseSettings;
1012
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
1113

1214
/**
@@ -30,6 +32,17 @@ protected void initialize() {
3032
preferenceScreen = getPreferenceScreen();
3133
Utils.sortPreferenceGroups(preferenceScreen);
3234
setPreferenceScreenToolbar(preferenceScreen);
35+
36+
// Clunky work around until preferences are custom classes that manage themselves.
37+
// Custom branding only works with non-root install. But the preferences must be
38+
// added during patched because of difficulties detecting during patching if it's
39+
// a root install. So instead the non-functional preferences are removed during
40+
// runtime if the app is mount (root) installation.
41+
if (GmsCoreSupport.isPackageNameOriginal()) {
42+
removePreferences(
43+
BaseSettings.CUSTOM_BRANDING_ICON.key,
44+
BaseSettings.CUSTOM_BRANDING_NAME.key);
45+
}
3346
} catch (Exception ex) {
3447
Logger.printException(() -> "initialize failure", ex);
3548
}

extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CustomBrandingPatch.java

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package app.revanced.extension.shared.patches;
22

3+
import android.app.Notification;
34
import android.content.ComponentName;
45
import android.content.Context;
56
import android.content.pm.PackageManager;
7+
import android.graphics.Color;
68

79
import java.util.ArrayList;
810
import java.util.List;
11+
import java.util.Locale;
912

1013
import app.revanced.extension.shared.GmsCoreSupport;
1114
import app.revanced.extension.shared.Logger;
@@ -29,28 +32,56 @@ public class CustomBrandingPatch {
2932
// The most that can be done is to hide a theme from the UI and keep the alias with dummy data.
3033
public enum BrandingTheme {
3134
/**
32-
* Original unpatched icon. Must be first enum.
35+
* Original unpatched icon.
3336
*/
34-
ORIGINAL("revanced_original"),
35-
ROUNDED("revanced_rounded"),
36-
MINIMAL("revanced_minimal"),
37-
SCALED("revanced_scaled"),
37+
ORIGINAL,
38+
ROUNDED,
39+
MINIMAL,
40+
SCALED,
3841
/**
39-
* User provided custom icon. Must be the last enum.
42+
* User provided custom icon.
4043
*/
41-
CUSTOM("revanced_custom");
42-
43-
public final String themeAlias;
44-
45-
BrandingTheme(String themeAlias) {
46-
this.themeAlias = themeAlias;
47-
}
44+
CUSTOM;
4845

4946
private String packageAndNameIndexToClassAlias(String packageName, int appIndex) {
5047
if (appIndex <= 0) {
5148
throw new IllegalArgumentException("App index starts at index 1");
5249
}
53-
return packageName + '.' + themeAlias + '_' + appIndex;
50+
return packageName + ".revanced_" + name().toLowerCase(Locale.US) + '_' + appIndex;
51+
}
52+
}
53+
54+
private static final int notificationSmallIcon;
55+
56+
static {
57+
BrandingTheme branding = BaseSettings.CUSTOM_BRANDING_ICON.get();
58+
if (branding == BrandingTheme.ORIGINAL) {
59+
notificationSmallIcon = 0;
60+
} else {
61+
// Original icon is quantum_ic_video_youtube_white_24
62+
String iconName = "revanced_notification_icon";
63+
if (branding == BrandingTheme.CUSTOM) {
64+
iconName += "_custom";
65+
}
66+
67+
notificationSmallIcon = Utils.getResourceIdentifier(iconName, "drawable");
68+
if (notificationSmallIcon == 0) {
69+
Logger.printException(() -> "Could not load notification small icon");
70+
}
71+
}
72+
}
73+
74+
/**
75+
* Injection point.
76+
*/
77+
public static void setNotificationIcon(Notification.Builder builder) {
78+
try {
79+
if (notificationSmallIcon != 0) {
80+
builder.setSmallIcon(notificationSmallIcon)
81+
.setColor(Color.TRANSPARENT); // Remove YT red tint.
82+
}
83+
} catch (Exception ex) {
84+
Logger.printException(() -> "setNotificationIcon failure", ex);
5485
}
5586
}
5687

extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.graphics.drawable.Drawable;
77
import android.os.Build;
88
import android.preference.Preference;
9+
import android.preference.PreferenceGroup;
910
import android.preference.PreferenceScreen;
1011
import android.util.TypedValue;
1112
import android.view.ViewGroup;
@@ -22,6 +23,24 @@
2223

2324
@SuppressWarnings({"deprecation", "NewApi"})
2425
public class ToolbarPreferenceFragment extends AbstractPreferenceFragment {
26+
27+
/**
28+
* Removes the list of preferences from this fragment, if they exist.
29+
* @param keys Preference keys.
30+
*/
31+
protected void removePreferences(String ... keys) {
32+
for (String key : keys) {
33+
Preference pref = findPreference(key);
34+
if (pref != null) {
35+
PreferenceGroup parent = pref.getParent();
36+
if (parent != null) {
37+
Logger.printDebug(() -> "Removing preference: " + key);
38+
parent.removePreference(pref);
39+
}
40+
}
41+
}
42+
}
43+
2544
/**
2645
* Sets toolbar for all nested preference screens.
2746
*/

extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/YouTubePreferenceFragment.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import android.preference.PreferenceScreen;
55
import android.widget.Toolbar;
66

7+
import app.revanced.extension.shared.GmsCoreSupport;
78
import app.revanced.extension.shared.Logger;
89
import app.revanced.extension.shared.Utils;
10+
import app.revanced.extension.shared.settings.BaseSettings;
911
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
1012
import app.revanced.extension.youtube.settings.YouTubeActivityHook;
1113

@@ -30,6 +32,17 @@ protected void initialize() {
3032
preferenceScreen = getPreferenceScreen();
3133
Utils.sortPreferenceGroups(preferenceScreen);
3234
setPreferenceScreenToolbar(preferenceScreen);
35+
36+
// Clunky work around until preferences are custom classes that manage themselves.
37+
// Custom branding only works with non-root install. But the preferences must be
38+
// added during patched because of difficulties detecting during patching if it's
39+
// a root install. So instead the non-functional preferences are removed during
40+
// runtime if the app is mount (root) installation.
41+
if (GmsCoreSupport.isPackageNameOriginal()) {
42+
removePreferences(
43+
BaseSettings.CUSTOM_BRANDING_ICON.key,
44+
BaseSettings.CUSTOM_BRANDING_NAME.key);
45+
}
3346
} catch (Exception ex) {
3447
Logger.printException(() -> "initialize failure", ex);
3548
}

patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ val customBrandingPatch = baseCustomBrandingPatch(
6161
originalLauncherIconName = "ic_launcher_release",
6262
originalAppName = "@string/app_launcher_name",
6363
originalAppPackageName = MUSIC_PACKAGE_NAME,
64-
copyExistingIntentsToAliases = false,
64+
isYouTubeMusic = true,
6565
numberOfPresetAppNames = 5,
6666
mainActivityOnCreateFingerprint = musicActivityOnCreateFingerprint,
6767
mainActivityName = MUSIC_MAIN_ACTIVITY_NAME,

0 commit comments

Comments
 (0)