diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java index 84fb868ac9..c101a154bd 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java @@ -2,11 +2,9 @@ package app.revanced.extension.youtube.patches; import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*; -import static app.revanced.extension.youtube.patches.VersionCheckPatch.*; import android.util.DisplayMetrics; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; @@ -21,7 +19,7 @@ import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.youtube.settings.Settings; -@SuppressWarnings({"unused", "SpellCheckingInspection"}) +@SuppressWarnings("unused") public final class MiniplayerPatch { /** @@ -120,15 +118,6 @@ public final class MiniplayerPatch { private static final MiniplayerType CURRENT_TYPE = Settings.MINIPLAYER_TYPE.get(); - /** - * Cannot turn off double tap with modern 2 or 3 with later targets, - * as forcing it off breakings tapping the miniplayer. - */ - private static final boolean DOUBLE_TAP_ACTION_ENABLED = - // 19.29+ is very broken if double tap is not enabled. - IS_19_29_OR_GREATER || - (CURRENT_TYPE.isModern() && Settings.MINIPLAYER_DOUBLE_TAP_ACTION.get()); - private static final boolean DRAG_AND_DROP_ENABLED = CURRENT_TYPE.isModern() && !Settings.MINIPLAYER_DISABLE_DRAG_AND_DROP.get(); @@ -142,8 +131,7 @@ public final class MiniplayerPatch { // 19.25 is last version that uses forward/back buttons for phones, // but buttons still show for tablets/foldable devices, and they don't work well so always hide. - private static final boolean HIDE_REWIND_FORWARD_ENABLED = CURRENT_TYPE == MODERN_1 - && (VersionCheckPatch.IS_19_34_OR_GREATER || Settings.MINIPLAYER_HIDE_REWIND_FORWARD.get()); + private static final boolean HIDE_REWIND_FORWARD_ENABLED = CURRENT_TYPE == MODERN_1; private static final boolean MINIPLAYER_ROUNDED_CORNERS_ENABLED = CURRENT_TYPE.isModern() && !Settings.MINIPLAYER_DISABLE_ROUNDED_CORNERS.get(); @@ -151,13 +139,6 @@ public final class MiniplayerPatch { private static final boolean MINIPLAYER_HORIZONTAL_DRAG_ENABLED = DRAG_AND_DROP_ENABLED && !Settings.MINIPLAYER_DISABLE_HORIZONTAL_DRAG.get(); - /** - * Remove a broken and always present subtitle text that is only - * present with {@link MiniplayerType#MODERN_2}. Bug was fixed in 19.21. - */ - private static final boolean HIDE_BROKEN_MODERN_2_SUBTITLE = - CURRENT_TYPE == MODERN_2 && !IS_19_21_OR_GREATER; - private static final int OPACITY_LEVEL; static { @@ -190,11 +171,7 @@ public final class MiniplayerPatch { @Override public boolean isAvailable() { MiniplayerType type = Settings.MINIPLAYER_TYPE.get(); - return type == MODERN_4 - || (!IS_19_20_OR_GREATER && (type == MODERN_1 || type == MODERN_3)) - || (!IS_19_26_OR_GREATER && type == MODERN_1 - && !Settings.MINIPLAYER_DOUBLE_TAP_ACTION.get() && Settings.MINIPLAYER_DISABLE_DRAG_AND_DROP.get()) - || (IS_19_29_OR_GREATER && type == MODERN_3); + return type == MODERN_4; } @Override @@ -325,7 +302,7 @@ public final class MiniplayerPatch { return original; } - return DOUBLE_TAP_ACTION_ENABLED; + return true; } /** @@ -435,25 +412,4 @@ public final class MiniplayerPatch { Logger.printException(() -> "hideMiniplayerSubTexts failure", ex); } } - - /** - * Injection point. - */ - public static void playerOverlayGroupCreated(View group) { - try { - if (HIDE_BROKEN_MODERN_2_SUBTITLE && MODERN_OVERLAY_SUBTITLE_TEXT != 0) { - if (group instanceof ViewGroup) { - View subtitleText = Utils.getChildView((ViewGroup) group, true, - view -> view.getId() == MODERN_OVERLAY_SUBTITLE_TEXT); - - if (subtitleText != null) { - subtitleText.setVisibility(View.GONE); - Logger.printDebug(() -> "Modern overlay subtitle view set to hidden"); - } - } - } - } catch (Exception ex) { - Logger.printException(() -> "playerOverlayGroupCreated failure", ex); - } - } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ShortsAutoplayPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ShortsAutoplayPatch.java index 905ca6dfa0..0437a08e4d 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ShortsAutoplayPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ShortsAutoplayPatch.java @@ -81,13 +81,6 @@ public class ShortsAutoplayPatch { final boolean autoplay; if (isAppInBackgroundPiPMode()) { - if (!VersionCheckPatch.IS_19_34_OR_GREATER) { - // 19.34+ is required to set background play behavior. - Logger.printDebug(() -> "PiP Shorts not supported, using original repeat behavior"); - - return original; - } - autoplay = Settings.SHORTS_AUTOPLAY_BACKGROUND.get(); } else { autoplay = Settings.SHORTS_AUTOPLAY.get(); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java index 77d85737b5..b68e4c39af 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java @@ -7,19 +7,6 @@ public class VersionCheckPatch { return Utils.getAppVersionName().compareTo(version) >= 0; } - @Deprecated - public static final boolean IS_19_17_OR_GREATER = isVersionOrGreater("19.17.00"); - @Deprecated - public static final boolean IS_19_20_OR_GREATER = isVersionOrGreater("19.20.00"); - @Deprecated - public static final boolean IS_19_21_OR_GREATER = isVersionOrGreater("19.21.00"); - @Deprecated - public static final boolean IS_19_26_OR_GREATER = isVersionOrGreater("19.26.00"); - @Deprecated - public static final boolean IS_19_29_OR_GREATER = isVersionOrGreater("19.29.00"); - @Deprecated - public static final boolean IS_19_34_OR_GREATER = isVersionOrGreater("19.34.00"); - public static final boolean IS_20_21_OR_GREATER = isVersionOrGreater("20.21.00"); public static final boolean IS_20_22_OR_GREATER = isVersionOrGreater("20.22.00"); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/YouTubeActivityHook.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/YouTubeActivityHook.java index d95069898d..f556995f3d 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/YouTubeActivityHook.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/YouTubeActivityHook.java @@ -11,7 +11,6 @@ import app.revanced.extension.shared.ResourceType; import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.settings.BaseActivityHook; import app.revanced.extension.youtube.patches.VersionCheckPatch; -import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch; import app.revanced.extension.youtube.settings.preference.YouTubePreferenceFragment; import app.revanced.extension.youtube.settings.search.YouTubeSearchViewController; @@ -19,7 +18,7 @@ import app.revanced.extension.youtube.settings.search.YouTubeSearchViewControlle * Hooks LicenseActivity to inject a custom {@link YouTubePreferenceFragment} * with a toolbar and search functionality. */ -@SuppressWarnings("deprecation") + public class YouTubeActivityHook extends BaseActivityHook { /** @@ -121,17 +120,9 @@ public class YouTubeActivityHook extends BaseActivityHook { */ @SuppressWarnings("unused") public static boolean useCairoSettingsFragment(boolean original) { - // Early targets have layout issues and it's better to always force off. - if (!VersionCheckPatch.IS_19_34_OR_GREATER) { - return false; - } if (Settings.RESTORE_OLD_SETTINGS_MENUS.get()) { return false; } - // Spoofing can cause half broken settings menus of old and new settings. - if (SpoofAppVersionPatch.isSpoofingToLessThan("19.35.36")) { - return false; - } // On the first launch of a clean install, forcing the cairo menu can give a // half broken appearance because all the preference icons may not be available yet. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt index 0ef561d714..81297b8de4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt @@ -3,7 +3,6 @@ package app.revanced.patches.youtube.layout.miniplayer import app.revanced.com.android.tools.smali.dexlib2.mutable.MutableMethod -import app.revanced.com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable import app.revanced.patcher.classDef import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions @@ -24,19 +23,13 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.util.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.immutable.ImmutableMethod -import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter -// Only available in 19.15 and upwards. -internal var ytOutlineXWhite24 = -1L - private set internal var ytOutlinePictureInPictureWhite24 = -1L private set @@ -50,13 +43,6 @@ private val miniplayerResourcePatch = resourcePatch { // Resource id is not used during patching, but is used by extension. // Verify the resource is present while patching. ResourceType.ID["modern_miniplayer_subtitle_text"] - - // Only required for exactly 19.16 - if (!is_19_17_or_greater) { - ytOutlinePictureInPictureWhite24 = - ResourceType.DRAWABLE["yt_outline_picture_in_picture_white_24"] - ytOutlineXWhite24 = ResourceType.DRAWABLE["yt_outline_x_white_24"] - } } } @@ -94,64 +80,24 @@ val miniplayerPatch = bytecodePatch( preferences += if (is_20_37_or_greater) { ListPreference("revanced_miniplayer_type") - } else if (is_20_03_or_greater) { + } else { ListPreference( key = "revanced_miniplayer_type", entriesKey = "revanced_miniplayer_type_legacy_20_03_entries", entryValuesKey = "revanced_miniplayer_type_legacy_20_03_entry_values", ) - } else if (is_19_43_or_greater) { - ListPreference( - key = "revanced_miniplayer_type", - entriesKey = "revanced_miniplayer_type_legacy_19_43_entries", - entryValuesKey = "revanced_miniplayer_type_legacy_19_43_entry_values", - ) - } else { - ListPreference( - key = "revanced_miniplayer_type", - entriesKey = "revanced_miniplayer_type_legacy_19_16_entries", - entryValuesKey = "revanced_miniplayer_type_legacy_19_16_entry_values", - ) } - if (is_19_25_or_greater) { - if (!is_19_29_or_greater) { - preferences += SwitchPreference("revanced_miniplayer_double_tap_action") - } - preferences += SwitchPreference("revanced_miniplayer_disable_drag_and_drop") - } - - if (is_19_43_or_greater) { - preferences += SwitchPreference("revanced_miniplayer_disable_horizontal_drag") - } - - if (is_19_36_or_greater) { - preferences += SwitchPreference("revanced_miniplayer_disable_rounded_corners") - } - + preferences += SwitchPreference("revanced_miniplayer_disable_drag_and_drop") + preferences += SwitchPreference("revanced_miniplayer_disable_horizontal_drag") + preferences += SwitchPreference("revanced_miniplayer_disable_rounded_corners") preferences += SwitchPreference("revanced_miniplayer_hide_subtext") + preferences += SwitchPreference("revanced_miniplayer_hide_overlay_buttons") - preferences += if (is_19_26_or_greater) { - SwitchPreference("revanced_miniplayer_hide_overlay_buttons") - } else { - SwitchPreference( - key = "revanced_miniplayer_hide_overlay_buttons", - titleKey = "revanced_miniplayer_hide_overlay_buttons_legacy_title", - summaryOnKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_on", - summaryOffKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_off", - ) - } - - if (!is_19_26_or_greater) { - preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward") - } - - if (is_19_26_or_greater) { - preferences += TextPreference( - "revanced_miniplayer_width_dip", - inputType = InputType.NUMBER - ) - } + preferences += TextPreference( + "revanced_miniplayer_width_dip", + inputType = InputType.NUMBER + ) preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER) @@ -283,109 +229,74 @@ val miniplayerPatch = bytecodePatch( } } - if (is_19_23_or_greater) { - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_DRAG_DROP_FEATURE_KEY, - "getMiniplayerDragAndDrop", + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_DRAG_DROP_FEATURE_KEY, + "getMiniplayerDragAndDrop", + ) + + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_MODERN_FEATURE_LEGACY_KEY, + "getModernMiniplayerOverride", + ) + + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_MODERN_FEATURE_KEY, + "getModernFeatureFlagsActiveOverride", + ) + + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_DOUBLE_TAP_FEATURE_KEY, + "getMiniplayerDoubleTapAction", + ) + + miniplayerModernConstructorMethod.apply { + val literalIndex = indexOfFirstLiteralInstructionOrThrow( + MINIPLAYER_INITIAL_SIZE_FEATURE_KEY, + ) + val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT) + val register = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getMiniplayerDefaultSize(I)I + move-result v$register + """, ) } - if (is_19_25_or_greater) { - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_MODERN_FEATURE_LEGACY_KEY, - "getModernMiniplayerOverride", - ) + // Override a minimum size constant. + miniplayerMinimumSizeMethodMatch.let { + it.method.apply { + val index = it[1] + val register = getInstruction(index).registerA - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_MODERN_FEATURE_KEY, - "getModernFeatureFlagsActiveOverride", - ) - - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_DOUBLE_TAP_FEATURE_KEY, - "getMiniplayerDoubleTapAction", - ) - } - - if (is_19_26_or_greater) { - miniplayerModernConstructorMethod.apply { - val literalIndex = indexOfFirstLiteralInstructionOrThrow( - MINIPLAYER_INITIAL_SIZE_FEATURE_KEY, - ) - val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT) - val register = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, - """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getMiniplayerDefaultSize(I)I - move-result v$register - """, - ) - } - - // Override a minimum size constant. - miniplayerMinimumSizeMethodMatch.let { - it.method.apply { - val index = it[1] - val register = getInstruction(index).registerA - - // Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller. - // The 170 initial limit probably could be patched to allow even smaller initial sizes, - // but 170 is already half the horizontal space and smaller does not seem useful. - replaceInstruction(index, "const/16 v$register, 170") - } + // Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller. + // The 170 initial limit probably could be patched to allow even smaller initial sizes, + // but 170 is already half the horizontal space and smaller does not seem useful. + replaceInstruction(index, "const/16 v$register, 170") } } - if (is_19_36_or_greater) { - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY, - "getRoundedCorners", - ) - } + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY, + "getRoundedCorners", + ) - if (is_19_43_or_greater) { - miniplayerOnCloseHandlerMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_DISABLED_FEATURE_KEY, - "getMiniplayerOnCloseHandler", - ) + miniplayerOnCloseHandlerMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_DISABLED_FEATURE_KEY, + "getMiniplayerOnCloseHandler", + ) - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY, - "getHorizontalDrag", - ) + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY, + "getHorizontalDrag", + ) - miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( - MINIPLAYER_ANIMATED_EXPAND_FEATURE_KEY, - "getMaximizeAnimation", - ) - } - - // endregion - - // region Fix 19.16 using mixed up drawables for tablet modern. - // YT fixed this mistake in 19.17. - // Fix this, by swapping the drawable resource values with each other. - if (!is_19_17_or_greater) { - miniplayerModernViewParentMethod.immutableClassDef.getMiniplayerModernExpandCloseDrawablesMethod() - .apply { - listOf( - ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24, - ytOutlineXWhite24 to ytOutlinePictureInPictureWhite24, - ).forEach { (originalResource, replacementResource) -> - val imageResourceIndex = - indexOfFirstLiteralInstructionOrThrow(originalResource) - val register = - getInstruction(imageResourceIndex).registerA - - replaceInstruction( - imageResourceIndex, - "const v$register, $replacementResource" - ) - } - } - } + miniplayerModernConstructorMethod.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_ANIMATED_EXPAND_FEATURE_KEY, + "getMaximizeAnimation", + ) // endregion @@ -443,45 +354,6 @@ val miniplayerPatch = bytecodePatch( "hideMiniplayerSubTexts(Landroid/view/View;)V", ) - // Modern 2 has a broken overlay subtitle view that is always present. - // Modern 2 uses the same overlay controls as the regular video player, - // and the overlay views are added at runtime. - // Add a hook to the overlay class, and pass the added views to extension. - // Problem is fixed in 19.21+ - // - // NOTE: Modern 2 uses the same video UI as the regular player except resized to smaller. - // This patch code could be used to hide other player overlays that do not use Litho. - if (!is_19_17_or_greater) { - playerOverlaysLayoutMethod.classDef.methods.add( - ImmutableMethod( - YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME, - "addView", - listOf( - ImmutableMethodParameter("Landroid/view/View;", null, null), - ImmutableMethodParameter("I", null, null), - ImmutableMethodParameter( - "Landroid/view/ViewGroup\$LayoutParams;", - null, - null, - ), - ), - "V", - AccessFlags.PUBLIC.value, - null, - null, - MutableMethodImplementation(4), - ).toMutable().apply { - addInstructions( - """ - invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V - invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V - return-void - """, - ) - }, - ) - } - // endregion } }