diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java index 2156bc693..4e3405860 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java @@ -2,6 +2,7 @@ package app.revanced.extension.youtube.patches.theme; import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.Utils.clamp; +import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle; import android.content.res.Resources; import android.graphics.Color; @@ -173,23 +174,15 @@ public final class SeekbarColorPatch { */ public static void setSplashAnimationLottie(LottieAnimationView view, int resourceId) { try { - if (!SEEKBAR_CUSTOM_COLOR_ENABLED) { + SplashScreenAnimationStyle animationStyle = Settings.SPLASH_SCREEN_ANIMATION_STYLE.get(); + if (!SEEKBAR_CUSTOM_COLOR_ENABLED + // Black and white animations cannot use color replacements. + || animationStyle == SplashScreenAnimationStyle.FPS_30_BLACK_AND_WHITE + || animationStyle == SplashScreenAnimationStyle.FPS_60_BLACK_AND_WHITE) { view.patch_setAnimation(resourceId); return; } - //noinspection ConstantConditions - if (false) { // Set true to force slow animation for development. - final int longAnimation = Utils.getResourceIdentifier( - Utils.isDarkModeEnabled() - ? "startup_animation_5s_30fps_dark" - : "startup_animation_5s_30fps_light", - "raw"); - if (longAnimation != 0) { - resourceId = longAnimation; - } - } - // Must specify primary key name otherwise the morphing YT logo color is also changed. String originalKey = "\"k\":"; String originalPrimary = originalKey + "[1,0,0.2,1]"; @@ -199,21 +192,16 @@ public final class SeekbarColorPatch { String replacementAccent = originalKey + getColorStringArray(customSeekbarColorGradient[1]); String json = loadRawResourceAsString(resourceId); - if (json == null) { - return; // Should never happen. - } + String replacement = json + .replace(originalPrimary, replacementPrimary) + .replace(originalAccent, replacementAccent); if (BaseSettings.DEBUG.get() && (!json.contains(originalPrimary) || !json.contains(originalAccent))) { - String jsonFinal = json; - Logger.printException(() -> "Could not replace launch animation colors: " + jsonFinal); + Logger.printException(() -> "Could not replace splash animation colors: " + json); } - Logger.printDebug(() -> "Replacing Lottie animation JSON"); - json = json.replace(originalPrimary, replacementPrimary); - json = json.replace(originalAccent, replacementAccent); - // cacheKey is not needed since the animation will not be reused. - view.patch_setAnimation(new ByteArrayInputStream(json.getBytes()), null); + view.patch_setAnimation(new ByteArrayInputStream(replacement.getBytes()), null); } catch (Exception ex) { Logger.printException(() -> "setSplashAnimationLottie failure", ex); } @@ -234,8 +222,7 @@ public final class SeekbarColorPatch { Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name()).useDelimiter("\\A")) { return scanner.next(); } catch (IOException e) { - Logger.printException(() -> "Could not load resource: " + resourceId); - return null; + throw new IllegalStateException("Could not load resource: " + resourceId); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ThemePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ThemePatch.java index 0a8dfda9b..38591ba79 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ThemePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ThemePatch.java @@ -1,11 +1,49 @@ package app.revanced.extension.youtube.patches.theme; +import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle.styleFromOrdinal; + +import androidx.annotation.Nullable; + +import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; import app.revanced.extension.youtube.ThemeHelper; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") public class ThemePatch { + + public enum SplashScreenAnimationStyle { + DEFAULT(0), + FPS_60_ONE_SECOND(1), + FPS_60_TWO_SECOND(2), + FPS_60_FIVE_SECOND(3), + FPS_60_BLACK_AND_WHITE(4), + FPS_30_ONE_SECOND(5), + FPS_30_TWO_SECOND(6), + FPS_30_FIVE_SECOND(7), + FPS_30_BLACK_AND_WHITE(8); + // There exists a 10th json style used as the switch statement default, + // but visually it is identical to 60fps one second. + + @Nullable + static SplashScreenAnimationStyle styleFromOrdinal(int style) { + // Alternatively can return using values()[style] + for (SplashScreenAnimationStyle value : values()) { + if (value.style == style) { + return value; + } + } + + return null; + } + + final int style; + + SplashScreenAnimationStyle(int style) { + this.style = style; + } + } + // color constants used in relation with litho components private static final int[] WHITE_VALUES = { -1, // comments chip background @@ -58,4 +96,22 @@ public class ThemePatch { public static boolean gradientLoadingScreenEnabled(boolean original) { return GRADIENT_LOADING_SCREEN_ENABLED; } + + /** + * Injection point. + */ + public static int getLoadingScreenType(int original) { + SplashScreenAnimationStyle style = Settings.SPLASH_SCREEN_ANIMATION_STYLE.get(); + if (style == SplashScreenAnimationStyle.DEFAULT) { + return original; + } + + final int replacement = style.style; + if (original != replacement) { + Logger.printDebug(() -> "Overriding splash screen style from: " + + styleFromOrdinal(original) + " to: " + style); + } + + return replacement; + } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 1ec8c44d4..9f0f06254 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -21,14 +21,12 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType; import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; import static app.revanced.extension.youtube.patches.components.PlayerFlyoutMenuItemsFilter.HideAudioFlyoutMenuAvailability; +import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE; -import app.revanced.extension.shared.settings.preference.SharedPrefCategory; -import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider.SwipeOverlayStyle; - import android.graphics.Color; import app.revanced.extension.shared.Logger; @@ -40,12 +38,14 @@ import app.revanced.extension.shared.settings.IntegerSetting; import app.revanced.extension.shared.settings.LongSetting; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.StringSetting; +import app.revanced.extension.shared.settings.preference.SharedPrefCategory; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime; import app.revanced.extension.youtube.patches.MiniplayerPatch; import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; +import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider.SwipeOverlayStyle; public class Settings extends BaseSettings { // Video @@ -226,6 +226,8 @@ public class Settings extends BaseSettings { public static final EnumSetting CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message"); public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true); public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true); + public static final EnumSetting SPLASH_SCREEN_ANIMATION_STYLE = new EnumSetting<>("splash_screen_animation_style", SplashScreenAnimationStyle.FPS_60_ONE_SECOND, true); + public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE, "revanced_remove_viewer_discretion_dialog_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message"); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt index a793eaa3c..f9c2d4e2b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt @@ -44,6 +44,19 @@ internal val themeHelperLightColorFingerprint = fingerprint { } } +internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L + internal val useGradientLoadingScreenFingerprint = fingerprint { literal { GRADIENT_LOADING_SCREEN_AB_CONSTANT } } + +internal const val SPLASH_SCREEN_STYLE_FEATURE_FLAG = 269032877L + +internal val splashScreenStyleFingerprint = fingerprint { + returns("V") + parameters("Landroid/os/Bundle;") + literal { SPLASH_SCREEN_STYLE_FEATURE_FLAG } + custom { method, classDef -> + method.name == "onCreate" && classDef.endsWith("/MainActivity;") + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt index 514eae710..bccab11eb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt @@ -10,6 +10,7 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.settings.preference.BasePreference import app.revanced.patches.shared.misc.settings.preference.InputType +import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference @@ -17,6 +18,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater +import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch @@ -27,8 +29,6 @@ import org.w3c.dom.Element private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/ThemePatch;" -internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L - val themePatch = bytecodePatch( name = "Theme", description = "Adds options for theming and applies a custom background theme (dark background theme defaults to amoled black).", @@ -232,15 +232,32 @@ val themePatch = bytecodePatch( addResources("youtube", "layout.theme.themePatch") PreferenceScreen.GENERAL_LAYOUT.addPreferences( - SwitchPreference("revanced_gradient_loading_screen"), + SwitchPreference("revanced_gradient_loading_screen") ) + if (is_19_47_or_greater) { + PreferenceScreen.GENERAL_LAYOUT.addPreferences( + ListPreference( + key = "splash_screen_animation_style", + summaryKey = null + ) + ) + } + useGradientLoadingScreenFingerprint.method.insertLiteralOverride( GRADIENT_LOADING_SCREEN_AB_CONSTANT, "$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z" ) - mapOf( + if (is_19_47_or_greater) { + // Lottie splash screen exists in earlier versions, but it may not be always on. + splashScreenStyleFingerprint.method.insertLiteralOverride( + SPLASH_SCREEN_STYLE_FEATURE_FLAG, + "$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I" + ) + } + + arrayOf( themeHelperLightColorFingerprint to lightThemeBackgroundColor, themeHelperDarkColorFingerprint to darkThemeBackgroundColor, ).forEach { (fingerprint, color) -> diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 7889a05dd..61cf1944b 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -187,6 +187,21 @@ AUTOMOTIVE + + + + @string/splash_screen_animation_style_entry_1 + @string/splash_screen_animation_style_entry_2 + + + FPS_60_ONE_SECOND + FPS_60_BLACK_AND_WHITE + + + @string/revanced_exit_fullscreen_entry_1 diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 5a08a20ae..e71a91d16 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1323,6 +1323,9 @@ Swipe to expand or close" Enable gradient loading screen Loading screen will have a gradient background Loading screen will have a solid background + Splash screen style + Color + Black and white Enable custom seekbar color Custom seekbar color is shown Original seekbar color is shown