fix(YouTube - Custom branding): Use ReVanced icon for status bar notification icon (#6108)

This commit is contained in:
LisoUseInAIKyrios
2025-10-14 09:54:14 +04:00
committed by GitHub
parent 5bd0f11630
commit 10ea250d4a
17 changed files with 407 additions and 207 deletions

View File

@@ -5,8 +5,10 @@ import android.preference.PreferenceScreen;
import android.widget.Toolbar;
import app.revanced.extension.music.settings.MusicActivityHook;
import app.revanced.extension.shared.GmsCoreSupport;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
/**
@@ -30,6 +32,17 @@ public class MusicPreferenceFragment extends ToolbarPreferenceFragment {
preferenceScreen = getPreferenceScreen();
Utils.sortPreferenceGroups(preferenceScreen);
setPreferenceScreenToolbar(preferenceScreen);
// Clunky work around until preferences are custom classes that manage themselves.
// Custom branding only works with non-root install. But the preferences must be
// added during patched because of difficulties detecting during patching if it's
// a root install. So instead the non-functional preferences are removed during
// runtime if the app is mount (root) installation.
if (GmsCoreSupport.isPackageNameOriginal()) {
removePreferences(
BaseSettings.CUSTOM_BRANDING_ICON.key,
BaseSettings.CUSTOM_BRANDING_NAME.key);
}
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}

View File

@@ -1,11 +1,14 @@
package app.revanced.extension.shared.patches;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import app.revanced.extension.shared.GmsCoreSupport;
import app.revanced.extension.shared.Logger;
@@ -29,28 +32,56 @@ public class CustomBrandingPatch {
// The most that can be done is to hide a theme from the UI and keep the alias with dummy data.
public enum BrandingTheme {
/**
* Original unpatched icon. Must be first enum.
* Original unpatched icon.
*/
ORIGINAL("revanced_original"),
ROUNDED("revanced_rounded"),
MINIMAL("revanced_minimal"),
SCALED("revanced_scaled"),
ORIGINAL,
ROUNDED,
MINIMAL,
SCALED,
/**
* User provided custom icon. Must be the last enum.
* User provided custom icon.
*/
CUSTOM("revanced_custom");
public final String themeAlias;
BrandingTheme(String themeAlias) {
this.themeAlias = themeAlias;
}
CUSTOM;
private String packageAndNameIndexToClassAlias(String packageName, int appIndex) {
if (appIndex <= 0) {
throw new IllegalArgumentException("App index starts at index 1");
}
return packageName + '.' + themeAlias + '_' + appIndex;
return packageName + ".revanced_" + name().toLowerCase(Locale.US) + '_' + appIndex;
}
}
private static final int notificationSmallIcon;
static {
BrandingTheme branding = BaseSettings.CUSTOM_BRANDING_ICON.get();
if (branding == BrandingTheme.ORIGINAL) {
notificationSmallIcon = 0;
} else {
// Original icon is quantum_ic_video_youtube_white_24
String iconName = "revanced_notification_icon";
if (branding == BrandingTheme.CUSTOM) {
iconName += "_custom";
}
notificationSmallIcon = Utils.getResourceIdentifier(iconName, "drawable");
if (notificationSmallIcon == 0) {
Logger.printException(() -> "Could not load notification small icon");
}
}
}
/**
* Injection point.
*/
public static void setNotificationIcon(Notification.Builder builder) {
try {
if (notificationSmallIcon != 0) {
builder.setSmallIcon(notificationSmallIcon)
.setColor(Color.TRANSPARENT); // Remove YT red tint.
}
} catch (Exception ex) {
Logger.printException(() -> "setNotificationIcon failure", ex);
}
}

View File

@@ -6,6 +6,7 @@ import android.graphics.Insets;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.util.TypedValue;
import android.view.ViewGroup;
@@ -22,6 +23,24 @@ import app.revanced.extension.shared.settings.BaseActivityHook;
@SuppressWarnings({"deprecation", "NewApi"})
public class ToolbarPreferenceFragment extends AbstractPreferenceFragment {
/**
* Removes the list of preferences from this fragment, if they exist.
* @param keys Preference keys.
*/
protected void removePreferences(String ... keys) {
for (String key : keys) {
Preference pref = findPreference(key);
if (pref != null) {
PreferenceGroup parent = pref.getParent();
if (parent != null) {
Logger.printDebug(() -> "Removing preference: " + key);
parent.removePreference(pref);
}
}
}
}
/**
* Sets toolbar for all nested preference screens.
*/

View File

@@ -4,8 +4,10 @@ import android.app.Dialog;
import android.preference.PreferenceScreen;
import android.widget.Toolbar;
import app.revanced.extension.shared.GmsCoreSupport;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
import app.revanced.extension.youtube.settings.YouTubeActivityHook;
@@ -30,6 +32,17 @@ public class YouTubePreferenceFragment extends ToolbarPreferenceFragment {
preferenceScreen = getPreferenceScreen();
Utils.sortPreferenceGroups(preferenceScreen);
setPreferenceScreenToolbar(preferenceScreen);
// Clunky work around until preferences are custom classes that manage themselves.
// Custom branding only works with non-root install. But the preferences must be
// added during patched because of difficulties detecting during patching if it's
// a root install. So instead the non-functional preferences are removed during
// runtime if the app is mount (root) installation.
if (GmsCoreSupport.isPackageNameOriginal()) {
removePreferences(
BaseSettings.CUSTOM_BRANDING_ICON.key,
BaseSettings.CUSTOM_BRANDING_NAME.key);
}
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}