From ee67b763d5c5947a5b1ef4420b1efa820ed6af83 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Thu, 6 Mar 2025 14:56:32 +0200 Subject: [PATCH] fix(YouTube): Combine `Restore old video quality menu` and `Remember video quality` into `Video quality` patch (#4552) --- ...va => AdvancedVideoQualityMenuFilter.java} | 10 +- ...ava => AdvancedVideoQualityMenuPatch.java} | 25 ++-- .../extension/youtube/settings/Settings.java | 7 +- patches/api/patches.api | 4 + .../connectivity/wifi/spoof/SpoofWifiPatch.kt | 4 +- .../music/misc/spoof/SpoofClientPatch.kt | 2 +- .../tiktok/misc/settings/SettingsPatch.kt | 2 +- .../lockscreen/ShowOnLockscreenPatch.kt | 2 +- .../ad/getpremium/HideGetPremiumPatch.kt | 2 +- .../interaction/downloads/DownloadsPatch.kt | 2 +- .../navigation/NavigationButtonsPatch.kt | 2 +- .../DisableFullscreenAmbientModePatch.kt | 2 +- .../youtube/layout/theme/ThemePatch.kt | 43 +++--- .../misc/litho/filter/LithoFilterPatch.kt | 2 +- .../misc/playertype/PlayerTypeHookPatch.kt | 2 +- .../youtube/misc/settings/SettingsPatch.kt | 2 - .../quality/AdvancedVideoQualityMenuPatch.kt | 118 +++++++++++++++ .../youtube/video/quality/Fingerprints.kt | 39 +++++ .../quality/RememberVideoQualityPatch.kt | 85 ++++------- .../video/quality/VideoQualityPatch.kt | 48 +++++++ .../youtube/video/speed/PlaybackSpeedPatch.kt | 8 +- .../speed/button/PlaybackSpeedButtonPatch.kt | 8 +- .../speed/custom/CustomPlaybackSpeedPatch.kt | 8 +- .../remember/RememberPlaybackSpeedPatch.kt | 5 +- .../video/videoqualitymenu/Fingerprints.kt | 43 ------ .../RestoreOldVideoQualityMenuPatch.kt | 135 +----------------- .../resources/addresources/values/strings.xml | 15 +- 27 files changed, 324 insertions(+), 301 deletions(-) rename extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/{VideoQualityMenuFilterPatch.java => AdvancedVideoQualityMenuFilter.java} (70%) rename extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/{RestoreOldVideoQualityMenuPatch.java => AdvancedVideoQualityMenuPatch.java} (76%) create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter.java similarity index 70% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch.java rename to extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter.java index 7ee3cab77..66d78328d 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter.java @@ -2,20 +2,20 @@ package app.revanced.extension.youtube.patches.components; import androidx.annotation.Nullable; -import app.revanced.extension.youtube.patches.playback.quality.RestoreOldVideoQualityMenuPatch; +import app.revanced.extension.youtube.patches.playback.quality.AdvancedVideoQualityMenuPatch; import app.revanced.extension.youtube.settings.Settings; /** - * Abuse LithoFilter for {@link RestoreOldVideoQualityMenuPatch}. + * Abuse LithoFilter for {@link AdvancedVideoQualityMenuPatch}. */ -public final class VideoQualityMenuFilterPatch extends Filter { +public final class AdvancedVideoQualityMenuFilter extends Filter { // Must be volatile or synchronized, as litho filtering runs off main thread // and this field is then access from the main thread. public static volatile boolean isVideoQualityMenuVisible; - public VideoQualityMenuFilterPatch() { + public AdvancedVideoQualityMenuFilter() { addPathCallbacks(new StringFilterGroup( - Settings.RESTORE_OLD_VIDEO_QUALITY_MENU, + Settings.ADVANCED_VIDEO_QUALITY_MENU, "quick_quality_sheet_content.eml-js" )); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch.java similarity index 76% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java rename to extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch.java index 11874006e..e65b13f13 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch.java @@ -8,30 +8,30 @@ import android.widget.ListView; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; -import app.revanced.extension.youtube.patches.components.VideoQualityMenuFilterPatch; +import app.revanced.extension.youtube.patches.components.AdvancedVideoQualityMenuFilter; import app.revanced.extension.youtube.settings.Settings; /** - * This patch contains the logic to show the old video quality menu. + * This patch contains the logic to always open the advanced video quality menu. * Two methods are required, because the quality menu is a RecyclerView in the new YouTube version * and a ListView in the old one. */ @SuppressWarnings("unused") -public final class RestoreOldVideoQualityMenuPatch { +public final class AdvancedVideoQualityMenuPatch { /** * Injection point. */ public static void onFlyoutMenuCreate(RecyclerView recyclerView) { - if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; + if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return; recyclerView.getViewTreeObserver().addOnDrawListener(() -> { try { // Check if the current view is the quality menu. - if (!VideoQualityMenuFilterPatch.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) { + if (!AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) { return; } - VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false; + AdvancedVideoQualityMenuFilter.isVideoQualityMenuVisible = false; ViewParent quickQualityViewParent = Utils.getParentView(recyclerView, 3); if (!(quickQualityViewParent instanceof ViewGroup)) { @@ -39,16 +39,15 @@ public final class RestoreOldVideoQualityMenuPatch { } View firstChild = recyclerView.getChildAt(0); - if (!(firstChild instanceof ViewGroup)) { + if (!(firstChild instanceof ViewGroup firstChildGroup)) { return; } - ViewGroup advancedQualityParentView = (ViewGroup) firstChild; - if (advancedQualityParentView.getChildCount() < 4) { + if (firstChildGroup.getChildCount() < 4) { return; } - View advancedQualityView = advancedQualityParentView.getChildAt(3); + View advancedQualityView = firstChildGroup.getChildAt(3); if (advancedQualityView == null) { return; } @@ -71,7 +70,7 @@ public final class RestoreOldVideoQualityMenuPatch { * Used to force the creation of the advanced menu item for the Shorts quality flyout. */ public static boolean forceAdvancedVideoQualityMenuCreation(boolean original) { - return Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get() || original; + return Settings.ADVANCED_VIDEO_QUALITY_MENU.get() || original; } /** @@ -79,8 +78,8 @@ public final class RestoreOldVideoQualityMenuPatch { * * Used if spoofing to an old app version, and also used for the Shorts video quality flyout. */ - public static void showOldVideoQualityMenu(final ListView listView) { - if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; + public static void showAdvancedVideoQualityMenu(ListView listView) { + if (!Settings.ADVANCED_VIDEO_QUALITY_MENU.get()) return; listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { @Override 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 b8263829d..954d75bb6 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 @@ -47,14 +47,14 @@ import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; public class Settings extends BaseSettings { // Video - public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE); public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2); public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2); public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", FALSE); public static final IntegerSetting SHORTS_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_shorts_quality_default_wifi", -2, true); public static final IntegerSetting SHORTS_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_shorts_quality_default_mobile", -2, true); public static final BooleanSetting REMEMBER_SHORTS_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_shorts_quality_last_selected", FALSE); - public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE); + public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE); + public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE); // Speed public static final FloatSetting SPEED_TAP_AND_HOLD = new FloatSetting("revanced_speed_tap_and_hold", 2.0f, true); public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", FALSE); @@ -391,6 +391,7 @@ public class Settings extends BaseSettings { private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127); private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033"); private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE); + private static final BooleanSetting DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE); static { // region Migration @@ -411,6 +412,8 @@ public class Settings extends BaseSettings { migrateOldSettingToNew(DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN, HIDE_END_SCREEN_SUGGESTED_VIDEO); + migrateOldSettingToNew(DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU, ADVANCED_VIDEO_QUALITY_MENU); + // Migrate renamed enum. //noinspection deprecation if (MINIPLAYER_TYPE.get() == MiniplayerType.PHONE) { diff --git a/patches/api/patches.api b/patches/api/patches.api index 94aee7801..71401bc89 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1463,6 +1463,10 @@ public final class app/revanced/patches/youtube/video/quality/RememberVideoQuali public static final fun getRememberVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/video/quality/VideoQualityPatchKt { + public static final fun getVideoQualityPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/video/speed/PlaybackSpeedPatchKt { public static final fun getPlaybackSpeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt index ede9eb1dc..f6b01cda2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt @@ -5,10 +5,10 @@ import app.revanced.patches.all.misc.transformation.IMethodCall import app.revanced.patches.all.misc.transformation.filterMapInstruction35c import app.revanced.patches.all.misc.transformation.transformInstructionsPatch -internal const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = +private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/extension/all/connectivity/wifi/spoof/SpoofWifiPatch" -internal const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" +private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" @Suppress("unused") val spoofWifiPatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt index 88ab2ceb8..e6fb8e3fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt @@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/spoof/SpoofClientPatch;" // TODO: Replace this patch with spoofVideoStreamsPatch once possible. diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt index a48305177..5e19646e5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt @@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.FieldReference -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/tiktok/settings/AdPersonalizationActivityHook;" val settingsPatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/ShowOnLockscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/ShowOnLockscreenPatch.kt index 2d3325190..c4ab245ff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/ShowOnLockscreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/ShowOnLockscreenPatch.kt @@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/tudortmund/lockscreen/ShowOnLockscreenPatch;" @Suppress("unused") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt index c4fb21b15..49d7a460d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt @@ -11,7 +11,7 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HideGetPremiumPatch;" val hideGetPremiumPatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt index 8e5c95f24..22f971e42 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt @@ -50,7 +50,7 @@ private val downloadsResourcePatch = resourcePatch { } } -internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;" +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DownloadsPatch;" internal const val BUTTON_DESCRIPTOR = "Lapp/revanced/extension/youtube/videoplayer/ExternalDownloadButton;" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt index 6e560cf3f..dd6666bcf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt @@ -23,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;" val navigationButtonsPatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt index 816dad7b5..0b9badbe8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt @@ -14,7 +14,7 @@ import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal const val EXTENSION_CLASS_DESCRIPTOR = +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;" val disableFullscreenAmbientModePatch = bytecodePatch( 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 587e56c12..f99053c80 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 @@ -8,7 +8,10 @@ import app.revanced.patcher.patch.stringOption import app.revanced.patches.all.misc.resources.addResources 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.PreferenceCategory +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch @@ -71,6 +74,9 @@ val themePatch = bytecodePatch( ) dependsOn( + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, lithoColorHookPatch, seekbarColorPatch, versionCheckPatch, @@ -78,23 +84,31 @@ val themePatch = bytecodePatch( dependsOn( settingsPatch, resourceMappingPatch, - addResourcesPatch, ) execute { - addResources("youtube", "layout.theme.themeResourcePatch") - - PreferenceScreen.SEEKBAR.addPreferences( + val preferences = mutableSetOf( SwitchPreference("revanced_seekbar_custom_color"), TextPreference("revanced_seekbar_custom_color_primary", inputType = InputType.TEXT_CAP_CHARACTERS), ) if (is_19_25_or_greater) { - PreferenceScreen.SEEKBAR.addPreferences( - TextPreference("revanced_seekbar_custom_color_accent", inputType = InputType.TEXT_CAP_CHARACTERS), + preferences += TextPreference( + "revanced_seekbar_custom_color_accent", + inputType = InputType.TEXT_CAP_CHARACTERS ) } + PreferenceScreen.SEEKBAR.addPreferences( + PreferenceCategory( + // Title is hidden, but is used for sorting the group. + titleKey = "revanced_seekbar_custom_color_title", + sorting = Sorting.UNSORTED, + tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", + preferences = preferences + ) + ) + // Edit theme colors via resources. document("res/values/colors.xml").use { document -> @@ -125,7 +139,6 @@ val themePatch = bytecodePatch( colorValue: String, ) { document(resourceFile).use { document -> - val resourcesNode = document.getElementsByTagName("resources").item(0) as Element resourcesNode.appendChild( @@ -133,7 +146,7 @@ val themePatch = bytecodePatch( setAttribute("name", colorName) setAttribute("category", "color") textContent = colorValue - }, + } ) } } @@ -152,11 +165,10 @@ val themePatch = bytecodePatch( // Edit splash screen files and change the background color, // if the background colors are set. if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) { - val splashScreenResourceFiles = - listOf( - "res/drawable/quantum_launchscreen_youtube.xml", - "res/drawable-sw600dp/quantum_launchscreen_youtube.xml", - ) + val splashScreenResourceFiles = listOf( + "res/drawable/quantum_launchscreen_youtube.xml", + "res/drawable-sw600dp/quantum_launchscreen_youtube.xml", + ) splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile -> document(resourceFile).use { document -> @@ -200,10 +212,7 @@ val themePatch = bytecodePatch( } } } - }, - sharedExtensionPatch, - settingsPatch, - addResourcesPatch, + } ) compatibleWith( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt index 16a834083..d40ab3aa4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt @@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference lateinit var addLithoFilter: (String) -> Unit private set -internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;" +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/LithoFilterPatch;" val lithoFilterPatch = bytecodePatch( description = "Hooks the method which parses the bytes into a ComponentContext to filter components.", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt index f8dcf8b7e..b14de0cbe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt @@ -15,7 +15,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;" +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;" internal var reelWatchPlayerId = -1L private set diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 47eee24ee..3a84ca69d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -301,11 +301,9 @@ object PreferenceScreen : BasePreferenceScreen() { summaryKey = null, ) - // Don't sort, because title sorting scatters the custom color preferences. val SEEKBAR = Screen( key = "revanced_settings_screen_07_seekbar", summaryKey = null, - sorting = Sorting.UNSORTED, ) val SWIPE_CONTROLS = Screen( key = "revanced_settings_screen_08_swipe_controls", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt new file mode 100644 index 000000000..55285a56e --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt @@ -0,0 +1,118 @@ +package app.revanced.patches.youtube.video.quality + +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.resourcePatch +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.resourceMappingPatch +import app.revanced.patches.shared.misc.mapping.resourceMappings +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter +import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch +import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook +import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch +import app.revanced.patches.youtube.misc.settings.settingsPatch +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +internal var videoQualityBottomSheetListFragmentTitle = -1L + private set +internal var videoQualityQuickMenuAdvancedMenuDescription = -1L + private set + +private val advancedVideoQualityMenuResourcePatch = resourcePatch { + dependsOn(resourceMappingPatch) + + execute { + // Used for the old type of the video quality menu. + videoQualityBottomSheetListFragmentTitle = resourceMappings[ + "layout", + "video_quality_bottom_sheet_list_fragment_title", + ] + + videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[ + "string", + "video_quality_quick_menu_advanced_menu_description", + ] + } +} + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/playback/quality/AdvancedVideoQualityMenuPatch;" + +private const val FILTER_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/components/AdvancedVideoQualityMenuFilter;" + +internal val advancedVideoQualityMenuPatch = bytecodePatch { + dependsOn( + advancedVideoQualityMenuResourcePatch, + sharedExtensionPatch, + settingsPatch, + addResourcesPatch, + lithoFilterPatch, + recyclerViewTreeHookPatch, + ) + + execute { + addResources("youtube", "video.quality.advancedVideoQualityMenuPatch") + + settingsMenuVideoQualityGroup.add( + SwitchPreference("revanced_advanced_video_quality_menu") + ) + + // region Patch for the old type of the video quality menu. + // Used for regular videos when spoofing to old app version, + // and for the Shorts quality flyout on newer app versions. + + videoQualityMenuViewInflateFingerprint.let { + it.method.apply { + val checkCastIndex = it.patternMatch!!.endIndex + val listViewRegister = getInstruction(checkCastIndex).registerA + + addInstruction( + checkCastIndex + 1, + "invoke-static { v$listViewRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + + "showAdvancedVideoQualityMenu(Landroid/widget/ListView;)V", + ) + } + } + + // Force YT to add the 'advanced' quality menu for Shorts. + videoQualityMenuOptionsFingerprint.let { + val patternMatch = it.patternMatch!! + val startIndex = patternMatch.startIndex + val insertIndex = patternMatch.endIndex + if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex") + + it.method.apply { + val register = getInstruction(insertIndex).registerA + + // A condition controls whether to show the three or four items quality menu. + // Force the four items quality menu to make the "Advanced" item visible, necessary for the patch. + addInstructions( + insertIndex, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z + move-result v$register + """ + ) + } + } + + // endregion + + // region Patch for the new type of the video quality menu. + + addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR) + + // Required to check if the video quality menu is currently shown in order to click on the "Advanced" item. + addLithoFilter(FILTER_CLASS_DESCRIPTOR) + + // endregion + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt index e33674a38..5ce6da9c1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.video.quality import app.revanced.patcher.fingerprint +import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -35,3 +36,41 @@ internal val videoQualitySetterFingerprint = fingerprint { ) strings("menu_item_video_quality") } + + +internal val videoQualityMenuOptionsFingerprint = fingerprint { + accessFlags(AccessFlags.STATIC) + returns("[L") + parameters("Landroid/content/Context", "L", "L") + opcodes( + Opcode.CONST_4, // First instruction of method. + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu. + Opcode.IF_NEZ, + ) + literal { videoQualityQuickMenuAdvancedMenuDescription } +} + +internal val videoQualityMenuViewInflateFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("L") + parameters("L", "L", "L") + opcodes( + Opcode.INVOKE_SUPER, + Opcode.CONST, + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_16, + Opcode.INVOKE_VIRTUAL, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + ) + literal { videoQualityBottomSheetListFragmentTitle } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt index d7c5a354a..65036fc27 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt @@ -8,12 +8,9 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch 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 import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch -import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint import app.revanced.patches.youtube.video.information.onCreateHook @@ -25,10 +22,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/playback/quality/RememberVideoQualityPatch;" -val rememberVideoQualityPatch = bytecodePatch( - name = "Remember video quality", - description = "Adds an option to remember the last video quality selected.", -) { +val rememberVideoQualityPatch = bytecodePatch { dependsOn( sharedExtensionPatch, videoInformationPatch, @@ -37,59 +31,38 @@ val rememberVideoQualityPatch = bytecodePatch( addResourcesPatch, ) - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.45.38", - "19.46.42", - "19.47.53", - ), - ) - execute { addResources("youtube", "video.quality.rememberVideoQualityPatch") - PreferenceScreen.VIDEO.addPreferences( - // Keep the preferences organized together. - PreferenceCategory( - key = "revanced_01_video_key", // Dummy key to force the quality preferences first. - titleKey = null, - sorting = Sorting.UNSORTED, - tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", - preferences = setOf( - ListPreference( - key = "revanced_video_quality_default_mobile", - summaryKey = null, - entriesKey = "revanced_video_quality_default_entries", - entryValuesKey = "revanced_video_quality_default_entry_values", - ), - ListPreference( - key = "revanced_video_quality_default_wifi", - summaryKey = null, - entriesKey = "revanced_video_quality_default_entries", - entryValuesKey = "revanced_video_quality_default_entry_values", - ), - SwitchPreference("revanced_remember_video_quality_last_selected"), + settingsMenuVideoQualityGroup.addAll(listOf( + ListPreference( + key = "revanced_video_quality_default_mobile", + summaryKey = null, + entriesKey = "revanced_video_quality_default_entries", + entryValuesKey = "revanced_video_quality_default_entry_values", + ), + ListPreference( + key = "revanced_video_quality_default_wifi", + summaryKey = null, + entriesKey = "revanced_video_quality_default_entries", + entryValuesKey = "revanced_video_quality_default_entry_values", + ), + SwitchPreference("revanced_remember_video_quality_last_selected"), - ListPreference( - key = "revanced_shorts_quality_default_mobile", - summaryKey = null, - entriesKey = "revanced_video_quality_default_entries", - entryValuesKey = "revanced_video_quality_default_entry_values", - ), - ListPreference( - key = "revanced_shorts_quality_default_wifi", - summaryKey = null, - entriesKey = "revanced_video_quality_default_entries", - entryValuesKey = "revanced_video_quality_default_entry_values", - ), - SwitchPreference("revanced_remember_shorts_quality_last_selected") - ) - ) - ) + ListPreference( + key = "revanced_shorts_quality_default_mobile", + summaryKey = null, + entriesKey = "revanced_video_quality_default_entries", + entryValuesKey = "revanced_video_quality_default_entry_values", + ), + ListPreference( + key = "revanced_shorts_quality_default_wifi", + summaryKey = null, + entriesKey = "revanced_video_quality_default_entries", + entryValuesKey = "revanced_video_quality_default_entry_values", + ), + SwitchPreference("revanced_remember_shorts_quality_last_selected") + )) /* * The following code works by hooking the method which is called when the user selects a video quality diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt new file mode 100644 index 000000000..a01cf6f56 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt @@ -0,0 +1,48 @@ +package app.revanced.patches.youtube.video.quality + +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.shared.misc.settings.preference.BasePreference +import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting +import app.revanced.patches.youtube.misc.settings.PreferenceScreen + +/** + * Video quality settings. Used to organize all speed related settings together. + */ +internal val settingsMenuVideoQualityGroup = mutableSetOf() + +@Suppress("unused") +val videoQualityPatch = bytecodePatch( + name = "Video quality", + description = "Adds options to use the advanced video quality menu and set default video qualities." +) { + dependsOn( + rememberVideoQualityPatch, + advancedVideoQualityMenuPatch, + ) + + compatibleWith( + "com.google.android.youtube"( + "19.16.39", + "19.25.37", + "19.34.42", + "19.43.41", + "19.45.38", + "19.46.42", + "19.47.53", + ) + ) + + execute { + PreferenceScreen.VIDEO.addPreferences( + // Keep the preferences organized together. + PreferenceCategory( + key = "revanced_01_video_key", // Dummy key to force the quality preferences first. + titleKey = null, + sorting = Sorting.UNSORTED, + tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", + preferences = settingsMenuVideoQualityGroup + ) + ) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt index a5868887e..ef83ccb64 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt @@ -17,13 +17,13 @@ internal val settingsMenuVideoSpeedGroup = mutableSetOf() @Suppress("unused") val playbackSpeedPatch = bytecodePatch( name = "Playback speed", - description = "Adds options to customize available playback speeds, remember the last playback speed selected " + + description = "Adds options to customize available playback speeds, set default a playback speed, " + "and show a speed dialog button in the video player.", ) { dependsOn( - playbackSpeedButtonPatch, customPlaybackSpeedPatch, rememberPlaybackSpeedPatch, + playbackSpeedButtonPatch, ) compatibleWith( @@ -38,10 +38,10 @@ val playbackSpeedPatch = bytecodePatch( ) ) - finalize { + execute { PreferenceScreen.VIDEO.addPreferences( PreferenceCategory( - key = "revanced_zz_key", // Dummy key to force the speed settings last. + key = "revanced_zz_video_key", // Dummy key to force the speed settings last. titleKey = null, sorting = Sorting.UNSORTED, tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/button/PlaybackSpeedButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/button/PlaybackSpeedButtonPatch.kt index 1acc3ca74..0ac9b0769 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/button/PlaybackSpeedButtonPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/button/PlaybackSpeedButtonPatch.kt @@ -5,6 +5,7 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playercontrols.* import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch @@ -35,11 +36,12 @@ val playbackSpeedButtonPatch = bytecodePatch( description = "Adds the option to display playback speed dialog button in the video player.", ) { dependsOn( - playbackSpeedButtonResourcePatch, - customPlaybackSpeedPatch, - playerControlsPatch, + sharedExtensionPatch, settingsPatch, addResourcesPatch, + customPlaybackSpeedPatch, + playbackSpeedButtonResourcePatch, + playerControlsPatch, ) execute { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt index 84a560894..53151489b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt @@ -60,12 +60,12 @@ internal val customPlaybackSpeedPatch = bytecodePatch( ) { dependsOn( sharedExtensionPatch, - lithoFilterPatch, settingsPatch, - recyclerViewTreeHookPatch, - customPlaybackSpeedResourcePatch, addResourcesPatch, - versionCheckPatch + lithoFilterPatch, + versionCheckPatch, + recyclerViewTreeHookPatch, + customPlaybackSpeedResourcePatch ) execute { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/RememberPlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/RememberPlaybackSpeedPatch.kt index 94c69dd69..ad6ee4a6c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/RememberPlaybackSpeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/RememberPlaybackSpeedPatch.kt @@ -22,9 +22,9 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch { dependsOn( sharedExtensionPatch, settingsPatch, - videoInformationPatch, - customPlaybackSpeedPatch, addResourcesPatch, + videoInformationPatch, + customPlaybackSpeedPatch ) execute { @@ -44,6 +44,7 @@ internal val rememberPlaybackSpeedPatch = bytecodePatch { ) onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted") + userSelectedPlaybackSpeedHook( EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt deleted file mode 100644 index 7f5469da3..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.youtube.video.videoqualitymenu - -import app.revanced.patcher.fingerprint -import app.revanced.util.literal -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal val videoQualityMenuOptionsFingerprint = fingerprint { - accessFlags(AccessFlags.STATIC) - returns("[L") - parameters("Landroid/content/Context", "L", "L") - opcodes( - Opcode.CONST_4, // First instruction of method. - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu. - Opcode.IF_NEZ, - ) - literal { videoQualityQuickMenuAdvancedMenuDescription } -} - -internal val videoQualityMenuViewInflateFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("L") - parameters("L", "L", "L") - opcodes( - Opcode.INVOKE_SUPER, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_16, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ) - literal { videoQualityBottomSheetListFragmentTitle } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt index a10e916f7..537a2b68c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt @@ -1,135 +1,10 @@ package app.revanced.patches.youtube.video.videoqualitymenu -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.all.misc.resources.addResources -import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get -import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings -import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch -import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter -import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch -import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook -import app.revanced.patches.youtube.misc.recyclerviewtree.hook.recyclerViewTreeHookPatch -import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import app.revanced.patches.youtube.misc.settings.settingsPatch -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -internal var videoQualityBottomSheetListFragmentTitle = -1L - private set -internal var videoQualityQuickMenuAdvancedMenuDescription = -1L - private set - -private val restoreOldVideoQualityMenuResourcePatch = resourcePatch { - dependsOn( - settingsPatch, - resourceMappingPatch, - addResourcesPatch, - ) - - execute { - addResources("youtube", "video.videoqualitymenu.restoreOldVideoQualityMenuResourcePatch") - - PreferenceScreen.VIDEO.addPreferences( - SwitchPreference("revanced_restore_old_video_quality_menu"), - ) - - // Used for the old type of the video quality menu. - videoQualityBottomSheetListFragmentTitle = resourceMappings[ - "layout", - "video_quality_bottom_sheet_list_fragment_title", - ] - - videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[ - "string", - "video_quality_quick_menu_advanced_menu_description", - ] - } -} - -private const val FILTER_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/components/VideoQualityMenuFilterPatch;" - -private const val EXTENSION_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch;" +import app.revanced.patches.youtube.video.quality.videoQualityPatch @Suppress("unused") -val restoreOldVideoQualityMenuPatch = bytecodePatch( - name = "Restore old video quality menu", - description = "Adds an option to restore the old video quality menu with specific video resolution options.", - -) { - dependsOn( - sharedExtensionPatch, - restoreOldVideoQualityMenuResourcePatch, - lithoFilterPatch, - recyclerViewTreeHookPatch, - ) - - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.45.38", - "19.46.42", - "19.47.53", - ), - ) - - execute { - // region Patch for the old type of the video quality menu. - // Used for regular videos when spoofing to old app version, - // and for the Shorts quality flyout on newer app versions. - - videoQualityMenuViewInflateFingerprint.method.apply { - val checkCastIndex = videoQualityMenuViewInflateFingerprint.patternMatch!!.endIndex - val listViewRegister = getInstruction(checkCastIndex).registerA - - addInstruction( - checkCastIndex + 1, - "invoke-static { v$listViewRegister }, " + - "$EXTENSION_CLASS_DESCRIPTOR->" + - "showOldVideoQualityMenu(Landroid/widget/ListView;)V", - ) - } - - // Force YT to add the 'advanced' quality menu for Shorts. - val patternMatch = videoQualityMenuOptionsFingerprint.patternMatch!! - val startIndex = patternMatch.startIndex - if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex") - val insertIndex = patternMatch.endIndex - - videoQualityMenuOptionsFingerprint.method.apply { - val register = getInstruction(insertIndex).registerA - - // A condition controls whether to show the three or four items quality menu. - // Force the four items quality menu to make the "Advanced" item visible, necessary for the patch. - addInstructions( - insertIndex, - """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z - move-result v$register - """, - ) - } - - // endregion - - // region Patch for the new type of the video quality menu. - - addRecyclerViewTreeHook(EXTENSION_CLASS_DESCRIPTOR) - - // Required to check if the video quality menu is currently shown in order to click on the "Advanced" item. - addLithoFilter(FILTER_CLASS_DESCRIPTOR) - - // endregion - } -} +@Deprecated("Use 'Video Quality' instead.") +val restoreOldVideoQualityMenuPatch = bytecodePatch { + dependsOn(videoQualityPatch) +} \ No newline at end of file diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 5fa38af85..5b6df6e56 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1257,8 +1257,6 @@ Swipe to expand or close" Enable gradient loading screen Loading screen will have a gradient background Loading screen will have a solid background - - Enable custom seekbar color Custom seekbar color is shown Original seekbar color is shown @@ -1373,7 +1371,6 @@ Enabling this can unlock higher video qualities" - Video quality Auto Remember video quality changes Quality changes apply to all videos @@ -1381,8 +1378,8 @@ Enabling this can unlock higher video qualities" Default video quality on Wi-Fi network Default video quality on mobile network Remember Shorts quality changes - Quality changes apply to all Shorts videos - Quality changes only apply to the current Shorts video + Quality changes apply to all Shorts + Quality changes only apply to the current Short Default Shorts quality on Wi-Fi network Default Shorts quality on mobile network mobile @@ -1419,10 +1416,10 @@ Enabling this can unlock higher video qualities" HDR video is disabled HDR video is enabled - - Restore old video quality menu - Old video quality menu is shown - Old video quality menu is not shown + + Show advanced video quality menu + Advanced video quality menu is shown + Advanced video quality menu is not shown Enable slide to seek