From 8218c93f17ab11fdef44ddef7a429319551669e6 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:38:02 +0900 Subject: [PATCH] feat(YouTube Music - Player components): Add settings `Player background primary color` and `Player background secondary color` (Close https://github.com/inotia00/ReVanced_Extended/issues/2119) --- .../music/patches/player/PlayerPatch.java | 92 +++++++++++++++---- .../extension/music/settings/Settings.java | 8 +- .../ReVancedPreferenceFragment.java | 4 + .../components/PlayerComponentsPatch.kt | 53 ++++++----- .../music/settings/host/values/strings.xml | 11 ++- 5 files changed, 120 insertions(+), 48 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/player/PlayerPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/player/PlayerPatch.java index 3c148524d..2f74ede2e 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/player/PlayerPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/player/PlayerPatch.java @@ -1,5 +1,6 @@ package app.revanced.extension.music.patches.player; +import static app.revanced.extension.shared.utils.StringRef.str; import static app.revanced.extension.shared.utils.Utils.hideViewByRemovingFromParentUnderCondition; import static app.revanced.extension.shared.utils.Utils.hideViewUnderCondition; import static app.revanced.extension.shared.utils.Utils.isSDKAbove; @@ -11,11 +12,14 @@ import android.view.View; import org.apache.commons.lang3.ArrayUtils; import java.lang.ref.WeakReference; +import java.util.Arrays; import app.revanced.extension.music.settings.Settings; import app.revanced.extension.music.shared.VideoType; import app.revanced.extension.music.utils.VideoUtils; +import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.Utils; @SuppressWarnings({"unused", "SpellCheckingInspection"}) public class PlayerPatch { @@ -29,6 +33,10 @@ public class PlayerPatch { Settings.DISABLE_PLAYER_GESTURE.get(); private static final boolean ENABLE_SWIPE_TO_DISMISS_MINIPLAYER = Settings.ENABLE_SWIPE_TO_DISMISS_MINIPLAYER.get(); + private static final boolean ENABLE_ZEN_MODE = + Settings.ENABLE_ZEN_MODE.get(); + private static final boolean ENABLE_ZEN_MODE_PODCAST = + Settings.ENABLE_ZEN_MODE_PODCAST.get(); private static final boolean HIDE_DOUBLE_TAP_OVERLAY_FILTER = Settings.HIDE_DOUBLE_TAP_OVERLAY_FILTER.get(); private static final boolean HIDE_FULLSCREEN_SHARE_BUTTON = @@ -37,13 +45,45 @@ public class PlayerPatch { Settings.HIDE_SONG_VIDEO_TOGGLE.get(); private static final boolean RESTORE_OLD_COMMENTS_POPUP_PANELS = Settings.RESTORE_OLD_COMMENTS_POPUP_PANELS.get(); + private static final boolean SETTINGS_INITIALIZED = + Settings.SETTINGS_INITIALIZED.get(); - private static final int MUSIC_VIDEO_GREY_BACKGROUND_COLOR = 0xFF404040; - private static final int MUSIC_VIDEO_ORIGINAL_BACKGROUND_COLOR = 0xFF030303; + private static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY = + Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY; + private static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY = + Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY; + + private static final int ZEN_MODE_BACKGROUND_COLOR = 0xFF404040; + private static final int MUSIC_VIDEO_BACKGROUND_COLOR = 0xFF030303; + + private static final int[] MUSIC_VIDEO_GRADIENT_COLORS = {MUSIC_VIDEO_BACKGROUND_COLOR, MUSIC_VIDEO_BACKGROUND_COLOR}; + private static final int[] ZEN_MODE_GRADIENT_COLORS = {ZEN_MODE_BACKGROUND_COLOR, ZEN_MODE_BACKGROUND_COLOR}; + private static final int[] customColorGradient = new int[2]; + private static boolean colorInitalized = false; private static WeakReference previousButtonViewRef = new WeakReference<>(null); private static WeakReference nextButtonViewRef = new WeakReference<>(null); + static { + if (CHANGE_PLAYER_BACKGROUND_COLOR) + loadPlayerbackgroundColor(); + } + + private static void loadPlayerbackgroundColor() { + try { + customColorGradient[0] = Color.parseColor(CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.get()); + customColorGradient[1] = Color.parseColor(CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.get()); + colorInitalized = true; + } catch (Exception ex) { + Utils.showToastShort(str("revanced_custom_player_background_invalid_toast")); + Utils.showToastShort(str("revanced_extended_reset_to_default_toast")); + CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.resetToDefault(); + CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.resetToDefault(); + + loadPlayerbackgroundColor(); + } + } + public static boolean addMiniPlayerNextButton(boolean original) { return !ADD_MINIPLAYER_NEXT_BUTTON && original; } @@ -52,10 +92,26 @@ public class PlayerPatch { return Settings.CHANGE_MINIPLAYER_COLOR.get(); } - public static int changePlayerBackgroundColor(int originalColor) { - return CHANGE_PLAYER_BACKGROUND_COLOR && originalColor != MUSIC_VIDEO_GREY_BACKGROUND_COLOR - ? Color.BLACK - : originalColor; + public static int[] changePlayerBackgroundColor(int[] colors) { + if (Arrays.equals(MUSIC_VIDEO_GRADIENT_COLORS, colors)) { + final VideoType videoType = VideoType.getCurrent(); + final boolean isZenMode = ENABLE_ZEN_MODE && + (videoType.isMusicVideo() || (videoType.isPodCast() && ENABLE_ZEN_MODE_PODCAST)); + if (isZenMode) { + return ZEN_MODE_GRADIENT_COLORS; + } + } + if (CHANGE_PLAYER_BACKGROUND_COLOR && colorInitalized) { + return customColorGradient; + } + + return colors; + } + + public static boolean changeSeekBarPosition(boolean original) { + return SETTINGS_INITIALIZED + ? CHANGE_SEEK_BAR_POSITION + : original; } public static boolean disableMiniPlayerGesture() { @@ -137,9 +193,10 @@ public class PlayerPatch { } public static int enableZenMode(int originalColor) { - if (Settings.ENABLE_ZEN_MODE.get() && originalColor == MUSIC_VIDEO_ORIGINAL_BACKGROUND_COLOR) { - if (Settings.ENABLE_ZEN_MODE_PODCAST.get() || !VideoType.getCurrent().isPodCast()) { - return MUSIC_VIDEO_GREY_BACKGROUND_COLOR; + if (ENABLE_ZEN_MODE && originalColor == MUSIC_VIDEO_BACKGROUND_COLOR) { + final VideoType videoType = VideoType.getCurrent(); + if (videoType.isMusicVideo() || (videoType.isPodCast() && ENABLE_ZEN_MODE_PODCAST)) { + return ZEN_MODE_BACKGROUND_COLOR; } } return originalColor; @@ -162,9 +219,9 @@ public class PlayerPatch { } public static void setShuffleState(Enum shuffleState) { - if (!Settings.REMEMBER_SHUFFLE_SATE.get()) - return; - Settings.ALWAYS_SHUFFLE.save(shuffleState.ordinal() == 1); + if (Settings.REMEMBER_SHUFFLE_SATE.get()) { + Settings.ALWAYS_SHUFFLE.save(shuffleState.ordinal() == 1); + } } public static void shuffleTracks() { @@ -199,14 +256,13 @@ public class PlayerPatch { } public static boolean restoreOldCommentsPopUpPanels(boolean original) { - if (!Settings.SETTINGS_INITIALIZED.get()) { - return original; - } - return !RESTORE_OLD_COMMENTS_POPUP_PANELS && original; + return SETTINGS_INITIALIZED + ? !RESTORE_OLD_COMMENTS_POPUP_PANELS && original + : original; } public static boolean restoreOldPlayerBackground(boolean original) { - if (!Settings.SETTINGS_INITIALIZED.get()) { + if (!SETTINGS_INITIALIZED) { return original; } if (!isSDKAbove(23)) { @@ -220,7 +276,7 @@ public class PlayerPatch { } public static boolean restoreOldPlayerLayout(boolean original) { - if (!Settings.SETTINGS_INITIALIZED.get()) { + if (!SETTINGS_INITIALIZED) { return original; } return !Settings.RESTORE_OLD_PLAYER_LAYOUT.get(); diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java index 93e3dee01..0b1d92971 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java @@ -137,12 +137,14 @@ public class Settings extends BaseSettings { public static final BooleanSetting ADD_MINIPLAYER_PREVIOUS_BUTTON = new BooleanSetting("revanced_add_miniplayer_previous_button", TRUE, true); public static final BooleanSetting CHANGE_MINIPLAYER_COLOR = new BooleanSetting("revanced_change_miniplayer_color", TRUE); public static final BooleanSetting CHANGE_PLAYER_BACKGROUND_COLOR = new BooleanSetting("revanced_change_player_background_color", FALSE, true); + public static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY = new StringSetting("revanced_custom_player_background_color_primary", "#000000", true); + public static final StringSetting CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY = new StringSetting("revanced_custom_player_background_color_secondary", "#000000", true); public static final BooleanSetting DISABLE_MINIPLAYER_GESTURE = new BooleanSetting("revanced_disable_miniplayer_gesture", FALSE, true); public static final BooleanSetting DISABLE_PLAYER_GESTURE = new BooleanSetting("revanced_disable_player_gesture", FALSE, true); public static final BooleanSetting ENABLE_FORCED_MINIPLAYER = new BooleanSetting("revanced_enable_forced_miniplayer", TRUE); public static final BooleanSetting ENABLE_SWIPE_TO_DISMISS_MINIPLAYER = new BooleanSetting("revanced_enable_swipe_to_dismiss_miniplayer", TRUE, true); - public static final BooleanSetting ENABLE_ZEN_MODE = new BooleanSetting("revanced_enable_zen_mode", FALSE); - public static final BooleanSetting ENABLE_ZEN_MODE_PODCAST = new BooleanSetting("revanced_enable_zen_mode_podcast", FALSE); + public static final BooleanSetting ENABLE_ZEN_MODE = new BooleanSetting("revanced_enable_zen_mode", FALSE, true); + public static final BooleanSetting ENABLE_ZEN_MODE_PODCAST = new BooleanSetting("revanced_enable_zen_mode_podcast", FALSE, true); public static final BooleanSetting HIDE_COMMENT_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_comment_channel_guidelines", TRUE); public static final BooleanSetting HIDE_DOUBLE_TAP_OVERLAY_FILTER = new BooleanSetting("revanced_hide_double_tap_overlay_filter", FALSE, true); public static final BooleanSetting HIDE_COMMENT_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comment_timestamp_and_emoji_buttons", FALSE); @@ -262,6 +264,8 @@ public class Settings extends BaseSettings { CHANGE_START_PAGE.key, CUSTOM_FILTER_STRINGS.key, CUSTOM_PLAYBACK_SPEEDS.key, + CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY.key, + CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY.key, DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE.key, ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE.key, EXTERNAL_DOWNLOADER_PACKAGE_NAME.key, diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java index bc949490c..d06d664cd 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java @@ -4,6 +4,8 @@ import static app.revanced.extension.music.settings.Settings.BYPASS_IMAGE_REGION import static app.revanced.extension.music.settings.Settings.CHANGE_START_PAGE; import static app.revanced.extension.music.settings.Settings.CUSTOM_FILTER_STRINGS; import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYBACK_SPEEDS; +import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY; +import static app.revanced.extension.music.settings.Settings.CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY; import static app.revanced.extension.music.settings.Settings.DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE; import static app.revanced.extension.music.settings.Settings.ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE; import static app.revanced.extension.music.settings.Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME; @@ -139,6 +141,8 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { if (settings.equals(BYPASS_IMAGE_REGION_RESTRICTIONS_DOMAIN) || settings.equals(CUSTOM_FILTER_STRINGS) || settings.equals(CUSTOM_PLAYBACK_SPEEDS) + || settings.equals(CUSTOM_PLAYER_BACKGROUND_COLOR_PRIMARY) + || settings.equals(CUSTOM_PLAYER_BACKGROUND_COLOR_SECONDARY) || settings.equals(ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE) || settings.equals(HIDE_ACCOUNT_MENU_FILTER_STRINGS) || settings.equals(RETURN_YOUTUBE_USERNAME_YOUTUBE_DATA_API_V3_DEVELOPER_KEY)) { diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index 3fa1eef20..21c8a727b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -37,6 +37,7 @@ import app.revanced.patches.music.utils.resourceid.topEnd import app.revanced.patches.music.utils.resourceid.topStart import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus +import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.addSwitchPreference import app.revanced.patches.music.utils.settings.settingsPatch import app.revanced.patches.music.utils.videotype.videoTypeHookPatch @@ -48,6 +49,7 @@ import app.revanced.util.addStaticFieldToExtension import app.revanced.util.adoptChild import app.revanced.util.cloneMutable import app.revanced.util.doRecursively +import app.revanced.util.findInstructionIndicesReversed import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.injectLiteralInstructionViewCall @@ -391,7 +393,7 @@ val playerComponentsPatch = bytecodePatch( // endregion - // region patch for color match player and black player background + // region patch for color match player, change player background and enable zen mode (6.35+) val ( colorMathPlayerMethodParameter, @@ -406,17 +408,19 @@ val playerComponentsPatch = bytecodePatch( // black player background val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT) - val targetMethod = getWalkerMethod(invokeDirectIndex) - val insertIndex = targetMethod.indexOfFirstInstructionOrThrow(Opcode.IF_NE) - targetMethod.addInstructions( - insertIndex, """ - invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor(I)I - move-result p1 - invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor(I)I - move-result p2 - """ - ) + getWalkerMethod(invokeDirectIndex).apply { + val index = indexOfFirstInstructionOrThrow(Opcode.FILLED_NEW_ARRAY) + val register = getInstruction(index + 1).registerA + + addInstructions( + index + 2, """ + invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->changePlayerBackgroundColor([I)[I + move-result-object v$register + """ + ) + } + Triple( parameters, getInstruction(invokeVirtualIndex).reference, @@ -438,7 +442,6 @@ val playerComponentsPatch = bytecodePatch( }.forEach { method -> method.apply { val freeRegister = implementation!!.registerCount - parameters.size - 3 - val invokeDirectIndex = indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_DIRECT) val invokeDirectReference = @@ -472,6 +475,16 @@ val playerComponentsPatch = bytecodePatch( "revanced_change_player_background_color", "false" ) + addPreferenceWithIntent( + CategoryType.PLAYER, + "revanced_custom_player_background_color_primary", + "revanced_change_player_background_color" + ) + addPreferenceWithIntent( + CategoryType.PLAYER, + "revanced_custom_player_background_color_secondary", + "revanced_change_player_background_color" + ) // endregion @@ -708,7 +721,7 @@ val playerComponentsPatch = bytecodePatch( // endregion - // region patch for enable zen mode + // region patch for enable zen mode (~ 6.34) // this method is used for old player background (deprecated since YT Music v6.34.51) zenModeFingerprint.matchOrNull(miniPlayerConstructorFingerprint)?.let { @@ -728,20 +741,6 @@ val playerComponentsPatch = bytecodePatch( } } // no exception - switchToggleColorFingerprint.methodOrThrow(miniPlayerConstructorFingerprint).apply { - val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT) - val walkerMethod = getWalkerMethod(invokeDirectIndex) - - walkerMethod.addInstructions( - 0, """ - invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I - move-result p1 - invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I - move-result p2 - """ - ) - } - addSwitchPreference( CategoryType.PLAYER, "revanced_enable_zen_mode", diff --git a/patches/src/main/resources/music/settings/host/values/strings.xml b/patches/src/main/resources/music/settings/host/values/strings.xml index 1e4cf777e..56955b6bf 100644 --- a/patches/src/main/resources/music/settings/host/values/strings.xml +++ b/patches/src/main/resources/music/settings/host/values/strings.xml @@ -240,7 +240,16 @@ This does not bypass the age restriction. It just accepts it automatically."Change miniplayer color Changes the miniplayer color to match the fullscreen player. Change player background color - Changes the player background color to black. + Changes the player background color to custom color. + Player background primary color + "Type the hex code of the player background primary color. + +Use dark colors if possible, as the app does not support light themes." + Player background secondary color + "Type the hex code of the player background secondary color. + +Use dark colors if possible, as the app does not support light themes." + Invalid player background color. Disable miniplayer gesture Disables swipe to change tracks in the miniplayer. Disable player gesture