From 5116f5642daa89bccd12f432f8fc3a1b9a8b8937 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 4 Jun 2024 06:42:58 +0300 Subject: [PATCH 01/23] chore(YouTube - Spoof client): Update iOS summary disclaimer --- src/main/resources/addresources/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index dc0f814e..b4506ea3 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -1101,7 +1101,7 @@ Client is not spoofed\n\nVideo playback may not work Turning off this setting may cause video playback issues. Spoof client to iOS - Client is currently spoofed to iOS\n\nSide effects include:\n• No HDR video\n• Watch history may not work\n• Live streams cannot play as audio only\n• Live streams not available on older devices + Client is currently spoofed to iOS\n\nSide effects include:\n• No HDR video\n• Watch history may not work\n• Higher video qualities may be missing\n• Live streams cannot play as audio only\n• Live streams not available on Android 8.0 Client is currently spoofed to Android VR\n\nSide effects include:\n• No HDR video\n• Kids videos do not playback\n• Paused videos can randomly resume Spoof client thumbnails not available (API timed out) Spoof client thumbnails temporarily not available: %s From 64ac233782b9f5933558e9340f83733f3251535f Mon Sep 17 00:00:00 2001 From: KobeW50 <84587632+KobeW50@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:20:07 -0400 Subject: [PATCH 02/23] docs: Fix broken link (#3313) Co-authored-by: oSumAtrIX --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef79cf77..087ef822 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -115,7 +115,7 @@ with the maintainers of ReVanced Patches. This will help you determine whether y and whether it is worth your time to implement it 2. Development happens on the `dev` branch. Fork the repository and create your branch from `dev` 3. Commit your changes. In case you are contributing a new patch, make sure to follow the conventions for patches -described in the [documentation](https://github.com/ReVanced/revanced-patches/tree/docs/docs) +described in the [ReVanced Patcher documentation](https://github.com/ReVanced/revanced-patcher/tree/main/docs) 4. Submit a pull request to the `dev` branch of the repository and reference issues that your pull request closes in the description of your pull request 5. Our team will review your pull request and provide feedback. Once your pull request is approved, From 5511736b0c5dd409db6a68db0f85e389bb95be47 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 8 Jun 2024 01:48:12 +0300 Subject: [PATCH 03/23] feat(YouTube - Miniplayer): Rename `Tablet mini player` and allow selecting the style of the in-app miniplayer (#3302) Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 8 + .../misc/mapping/ResourceMappingPatch.kt | 8 +- .../layout/miniplayer/MiniplayerPatch.kt | 370 ++++++++++++++++++ .../miniplayer/MiniplayerResourcePatch.kt | 81 ++++ ...erDimensionsCalculatorParentFingerprint.kt | 13 + ...iplayerModernAddViewListenerFingerprint.kt | 14 + .../MiniplayerModernCloseButtonFingerprint.kt | 16 + .../MiniplayerModernConstructorFingerprint.kt | 11 + ...MiniplayerModernExpandButtonFingerprint.kt | 16 + ...erModernExpandCloseDrawablesFingerprint.kt | 16 + ...iniplayerModernForwardButtonFingerprint.kt | 16 + .../MiniplayerModernOverlayViewFingerprint.kt | 16 + ...MiniplayerModernRewindButtonFingerprint.kt | 16 + .../MiniplayerModernViewParentFingerprint.kt | 12 + .../MiniplayerOverrideFingerprint.kt} | 4 +- .../MiniplayerOverrideNoContextFingerprint.kt | 12 + ...layerResponseModelSizeCheckFingerprint.kt} | 12 +- .../YouTubePlayerOverlaysLayoutFingerprint.kt | 13 + .../CustomPlayerOverlayOpacityPatch.kt | 6 +- .../seekbar/SeekbarColorBytecodePatch.kt | 6 +- .../layout/tablet/EnableTabletLayoutPatch.kt | 55 ++- .../fingerprints/GetFormFactorFingerprint.kt | 3 +- .../tabletminiplayer/TabletMiniPlayerPatch.kt | 147 +------ ...erDimensionsCalculatorParentFingerprint.kt | 23 -- .../MiniPlayerOverrideNoContextFingerprint.kt | 11 - .../layout/theme/ThemeBytecodePatch.kt | 4 +- .../misc/fix/playback/SpoofClientPatch.kt | 5 +- .../CreatePlaybackSpeedMenuItemFingerprint.kt | 20 +- .../kotlin/app/revanced/util/BytecodeUtils.kt | 33 +- .../resources/addresources/values/arrays.xml | 29 ++ .../resources/addresources/values/strings.xml | 29 +- 31 files changed, 805 insertions(+), 220 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerResourcePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerDimensionsCalculatorParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernAddViewListenerFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernCloseButtonFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernConstructorFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandButtonFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandCloseDrawablesFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernForwardButtonFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernOverlayViewFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernRewindButtonFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernViewParentFingerprint.kt rename src/main/kotlin/app/revanced/patches/youtube/layout/{tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt => miniplayer/fingerprints/MiniplayerOverrideFingerprint.kt} (68%) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideNoContextFingerprint.kt rename src/main/kotlin/app/revanced/patches/youtube/layout/{tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt => miniplayer/fingerprints/MiniplayerResponseModelSizeCheckFingerprint.kt} (56%) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/YouTubePlayerOverlaysLayoutFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 75d89226..9f253870 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1528,6 +1528,12 @@ public final class app/revanced/patches/youtube/layout/hide/time/HideTimestampPa public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -1894,6 +1900,7 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat public final class app/revanced/util/BytecodeUtilsKt { public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod; + public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List; public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException; public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I @@ -1901,6 +1908,7 @@ public final class app/revanced/util/BytecodeUtilsKt { public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I + public static final fun indexOfFirstWideLiteralInstructionValueOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt index 388c4ef6..2c165e1f 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt @@ -1,6 +1,7 @@ package app.revanced.patches.shared.misc.mapping import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.ResourcePatch import org.w3c.dom.Element import java.util.* @@ -51,9 +52,10 @@ object ResourceMappingPatch : ResourcePatch() { threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) } - operator fun get(type: String, name: String) = resourceMappings.first { - it.type == type && it.name == name - }.id + operator fun get(type: String, name: String) = + resourceMappings.firstOrNull { + it.type == type && it.name == name + }?.id ?: throw PatchException("Could not find resource type: $type name: $name") data class ResourceElement(val type: String, val name: String, val id: Long) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt new file mode 100644 index 00000000..4d7c52a4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt @@ -0,0 +1,370 @@ +package app.revanced.patches.youtube.layout.miniplayer + +import app.revanced.patcher.data.BytecodeContext +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.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patches.all.misc.resources.AddResourcesPatch +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.PreferenceScreen +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.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.miniplayer.MiniplayerResourcePatch.modernMiniplayerClose +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.modernMiniplayerExpand +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.modernMiniplayerForwardButton +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.modernMiniplayerRewindButton +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.scrimOverlay +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.ytOutlinePictureInPictureWhite24 +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.ytOutlineXWhite24 +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerDimensionsCalculatorParentFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernAddViewListenerFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernCloseButtonFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernConstructorFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernExpandButtonFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernExpandCloseDrawablesFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernForwardButtonFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernOverlayViewFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernRewindButtonFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernViewParentFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerOverrideFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerOverrideNoContextFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerResponseModelSizeCheckFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.YouTubePlayerOverlaysLayoutFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.YouTubePlayerOverlaysLayoutFingerprint.YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME +import app.revanced.patches.youtube.layout.tablet.fingerprints.GetFormFactorFingerprint +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch +import app.revanced.util.findOpcodeIndicesReversed +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow +import app.revanced.util.patch.LiteralValueFingerprint +import app.revanced.util.resultOrThrow +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.Method +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +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.TypeReference +import com.android.tools.smali.dexlib2.immutable.ImmutableMethod +import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter + +// YT uses "Miniplayer" without a space between 'mini' and 'player: https://support.google.com/youtube/answer/9162927. +@Patch( + name = "Miniplayer", + description = "Adds options to change the in app minimized player, " + + "and if patching target 19.16+ adds options to use modern miniplayers.", + dependencies = [ + IntegrationsPatch::class, + SettingsPatch::class, + AddResourcesPatch::class, + MiniplayerResourcePatch::class + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", [ + "18.32.39", + "18.37.36", + "18.38.44", + "18.43.45", + "18.44.41", + "18.45.43", + "18.48.39", + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.38", + "19.10.39", + "19.11.43", + "19.12.41", + "19.13.37", + // 19.14 is left out, as it has incomplete miniplayer code and missing some UI resources. + // It's simpler to not bother with supporting this single old version. + // 19.15 has a different code for handling sub title texts, + // and also probably not worth making changes just to support this single old version. + "19.16.39" // Earliest supported version with modern miniplayers. + ] + ) + ] +) +@Suppress("unused") +object MiniplayerPatch : BytecodePatch( + setOf(GetFormFactorFingerprint, + MiniplayerDimensionsCalculatorParentFingerprint, + MiniplayerResponseModelSizeCheckFingerprint, + MiniplayerOverrideFingerprint, + MiniplayerModernConstructorFingerprint, + MiniplayerModernViewParentFingerprint, + YouTubePlayerOverlaysLayoutFingerprint + ) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/MiniplayerPatch;" + + override fun execute(context: BytecodeContext) { + AddResourcesPatch(this::class) + + // Modern mini player is only present and functional in 19.15+. + // Resource is not present in older versions. Using it to determine, if patching an old version. + val isPatchingOldVersion = ytOutlinePictureInPictureWhite24 < 0 + + SettingsPatch.PreferenceScreen.PLAYER.addPreferences( + PreferenceScreen( + key = "revanced_miniplayer_screen", + sorting = Sorting.UNSORTED, + preferences = + if (isPatchingOldVersion) { + setOf( + ListPreference( + "revanced_miniplayer_type", + summaryKey = null, + entriesKey = "revanced_miniplayer_type_legacy_entries", + entryValuesKey = "revanced_miniplayer_type_legacy_entry_values" + ) + ) + } else { + setOf( + ListPreference( + "revanced_miniplayer_type", + summaryKey = null, + entriesKey = "revanced_miniplayer_type_19_15_entries", + entryValuesKey = "revanced_miniplayer_type_19_15_entry_values" + ), + SwitchPreference("revanced_miniplayer_hide_expand_close"), + SwitchPreference("revanced_miniplayer_hide_subtext"), + SwitchPreference("revanced_miniplayer_hide_rewind_forward"), + TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER) + ) + } + ) + ) + + // region Enable tablet miniplayer. + + MiniplayerOverrideNoContextFingerprint.resolve( + context, + MiniplayerDimensionsCalculatorParentFingerprint.resultOrThrow().classDef + ) + MiniplayerOverrideNoContextFingerprint.resultOrThrow().mutableMethod.apply { + findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) } + } + + // endregion + + // region Legacy tablet Miniplayer hooks. + + MiniplayerOverrideFingerprint.resultOrThrow().let { + val appNameStringIndex = it.scanResult.stringsScanResult!!.matches.first().index + 2 + + it.mutableMethod.apply { + val walkerMethod = context.toMethodWalker(this) + .nextMethod(appNameStringIndex, true) + .getMethod() as MutableMethod + + walkerMethod.apply { + findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) } + } + } + } + + MiniplayerResponseModelSizeCheckFingerprint.resultOrThrow().let { + it.mutableMethod.insertLegacyTabletMiniplayerOverride(it.scanResult.patternScanResult!!.endIndex) + } + + if (isPatchingOldVersion) { + // Return here, as patch below is only intended for new versions of the app. + return + } + + // endregion + + + // region Enable modern miniplayer. + + MiniplayerModernConstructorFingerprint.resultOrThrow().mutableClass.methods.forEach { + it.apply { + if (AccessFlags.CONSTRUCTOR.isSet(accessFlags)) { + val iPutIndex = indexOfFirstInstructionOrThrow { + this.opcode == Opcode.IPUT && this.getReference()?.type == "I" + } + + insertModernMiniplayerTypeOverride(iPutIndex) + } else { + findReturnIndicesReversed().forEach { index -> insertModernMiniplayerOverride(index) } + } + } + } + + // 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. + + MiniplayerModernExpandCloseDrawablesFingerprint.apply { + resolve( + context, + MiniplayerModernViewParentFingerprint.resultOrThrow().classDef + ) + }.resultOrThrow().mutableMethod.apply { + listOf( + ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24, + ytOutlineXWhite24 to ytOutlinePictureInPictureWhite24, + ).forEach { (originalResource, replacementResource) -> + val imageResourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(originalResource) + val register = getInstruction(imageResourceIndex).registerA + + replaceInstruction(imageResourceIndex, "const v$register, $replacementResource") + } + } + + // endregion + + + // region Add hooks to hide tablet modern miniplayer buttons. + + listOf( + Triple(MiniplayerModernExpandButtonFingerprint, modernMiniplayerExpand,"hideMiniplayerExpandClose"), + Triple(MiniplayerModernCloseButtonFingerprint, modernMiniplayerClose, "hideMiniplayerExpandClose"), + Triple(MiniplayerModernRewindButtonFingerprint, modernMiniplayerRewindButton, "hideMiniplayerRewindForward"), + Triple(MiniplayerModernForwardButtonFingerprint, modernMiniplayerForwardButton, "hideMiniplayerRewindForward"), + Triple(MiniplayerModernOverlayViewFingerprint, scrimOverlay, "adjustMiniplayerOpacity") + ).forEach { (fingerprint, literalValue, methodName) -> + fingerprint.resolve( + context, + MiniplayerModernViewParentFingerprint.resultOrThrow().classDef + ) + + fingerprint.hookInflatedView( + literalValue, + "Landroid/widget/ImageView;", + "$INTEGRATIONS_CLASS_DESCRIPTOR->$methodName(Landroid/widget/ImageView;)V" + ) + } + + MiniplayerModernAddViewListenerFingerprint.apply { + resolve( + context, + MiniplayerModernViewParentFingerprint.resultOrThrow().classDef + ) + }.resultOrThrow().mutableMethod.addInstruction( + 0, + "invoke-static { p1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->" + + "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 integrations. + YouTubePlayerOverlaysLayoutFingerprint.resultOrThrow().mutableClass.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 }, $INTEGRATIONS_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V + return-void + """, + ) + } + ) + + // endregion + } + + private fun Method.findReturnIndicesReversed() = findOpcodeIndicesReversed(Opcode.RETURN) + + /** + * Adds an override to force legacy tablet miniplayer to be used or not used. + */ + private fun MutableMethod.insertLegacyTabletMiniplayerOverride(index: Int) { + insertBooleanOverride(index, "getLegacyTabletMiniplayerOverride") + } + + /** + * Adds an override to force modern miniplayer to be used or not used. + */ + private fun MutableMethod.insertModernMiniplayerOverride(index: Int) { + insertBooleanOverride(index, "getModernMiniplayerOverride") + } + + private fun MutableMethod.insertBooleanOverride(index: Int, methodName: String) { + val register = getInstruction(index).registerA + addInstructions( + index, + """ + invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->$methodName(Z)Z + move-result v$register + """ + ) + } + + /** + * Adds an override to specify which modern miniplayer is used. + */ + private fun MutableMethod.insertModernMiniplayerTypeOverride(iPutIndex: Int) { + val targetInstruction = getInstruction(iPutIndex) + val targetReference = (targetInstruction as ReferenceInstruction).reference + + addInstructions( + iPutIndex + 1, """ + invoke-static { v${targetInstruction.registerA} }, $INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I + move-result v${targetInstruction.registerA} + # Original instruction + iput v${targetInstruction.registerA}, v${targetInstruction.registerB}, $targetReference + """ + ) + removeInstruction(iPutIndex) + } + + private fun LiteralValueFingerprint.hookInflatedView( + literalValue: Long, + hookedClassType: String, + integrationsMethodName: String, + ) { + resultOrThrow().mutableMethod.apply { + val imageViewIndex = indexOfFirstInstructionOrThrow( + indexOfFirstWideLiteralInstructionValueOrThrow(literalValue) + ) { + opcode == Opcode.CHECK_CAST && getReference()?.type == hookedClassType + } + + val register = getInstruction(imageViewIndex).registerA + addInstruction( + imageViewIndex + 1, + "invoke-static { v$register }, $integrationsMethodName" + ) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerResourcePatch.kt new file mode 100644 index 00000000..3870f065 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerResourcePatch.kt @@ -0,0 +1,81 @@ +package app.revanced.patches.youtube.layout.miniplayer + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch + +@Patch(dependencies = [ResourceMappingPatch::class]) +internal object MiniplayerResourcePatch : ResourcePatch() { + var floatyBarButtonTopMargin = -1L + + // Only available in 19.15 and upwards. + var ytOutlineXWhite24 = -1L + var ytOutlinePictureInPictureWhite24 = -1L + var scrimOverlay = -1L + var modernMiniplayerClose = -1L + var modernMiniplayerExpand = -1L + var modernMiniplayerRewindButton = -1L + var modernMiniplayerForwardButton = -1L + var playerOverlays = -1L + + override fun execute(context: ResourceContext) { + floatyBarButtonTopMargin = ResourceMappingPatch[ + "dimen", + "floaty_bar_button_top_margin" + ] + + try { + ytOutlinePictureInPictureWhite24 = ResourceMappingPatch[ + "drawable", + "yt_outline_picture_in_picture_white_24" + ] + } catch (exception: PatchException) { + // Ignore, and assume the app is 19.14 or earlier. + return + } + + ytOutlineXWhite24 = ResourceMappingPatch[ + "drawable", + "yt_outline_x_white_24" + ] + + scrimOverlay = ResourceMappingPatch[ + "id", + "scrim_overlay" + ] + + modernMiniplayerClose = ResourceMappingPatch[ + "id", + "modern_miniplayer_close" + ] + + modernMiniplayerExpand = ResourceMappingPatch[ + "id", + "modern_miniplayer_expand" + ] + + modernMiniplayerRewindButton = ResourceMappingPatch[ + "id", + "modern_miniplayer_rewind_button" + ] + + modernMiniplayerForwardButton = ResourceMappingPatch[ + "id", + "modern_miniplayer_forward_button" + ] + + playerOverlays = ResourceMappingPatch[ + "layout", + "player_overlays" + ] + + // Resource id is not used during patching, but is used by integrations. + // Verify the resource is present while patching. + ResourceMappingPatch[ + "id", + "modern_miniplayer_subtitle_text" + ] + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerDimensionsCalculatorParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerDimensionsCalculatorParentFingerprint.kt new file mode 100644 index 00000000..bc156e7a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerDimensionsCalculatorParentFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object MiniplayerDimensionsCalculatorParentFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf("L"), + literalSupplier = { MiniplayerResourcePatch.floatyBarButtonTopMargin } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernAddViewListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernAddViewListenerFingerprint.kt new file mode 100644 index 00000000..c4e94724 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernAddViewListenerFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernAddViewListenerFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf("Landroid/view/View;") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernCloseButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernCloseButtonFingerprint.kt new file mode 100644 index 00000000..e4bbd9aa --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernCloseButtonFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernCloseButtonFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/widget/ImageView;", + parameters = listOf(), + literalSupplier = { MiniplayerResourcePatch.modernMiniplayerClose } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernConstructorFingerprint.kt new file mode 100644 index 00000000..0afb5e52 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernConstructorFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object MiniplayerModernConstructorFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("L"), + literalSupplier = { 45623000L } // Magic number found in the constructor. +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandButtonFingerprint.kt new file mode 100644 index 00000000..35629e30 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandButtonFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernExpandButtonFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/widget/ImageView;", + parameters = listOf(), + literalSupplier = { MiniplayerResourcePatch.modernMiniplayerExpand } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandCloseDrawablesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandCloseDrawablesFingerprint.kt new file mode 100644 index 00000000..9ee56819 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernExpandCloseDrawablesFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernExpandCloseDrawablesFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf("L"), + literalSupplier = { MiniplayerResourcePatch.ytOutlinePictureInPictureWhite24 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernForwardButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernForwardButtonFingerprint.kt new file mode 100644 index 00000000..52053750 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernForwardButtonFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernForwardButtonFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/widget/ImageView;", + parameters = listOf(), + literalSupplier = { MiniplayerResourcePatch.modernMiniplayerForwardButton } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernOverlayViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernOverlayViewFingerprint.kt new file mode 100644 index 00000000..02730f44 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernOverlayViewFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernOverlayViewFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf(), + literalSupplier = { MiniplayerResourcePatch.scrimOverlay } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernRewindButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernRewindButtonFingerprint.kt new file mode 100644 index 00000000..71b9c054 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernRewindButtonFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves using the class found in [MiniplayerModernViewParentFingerprint]. + */ +internal object MiniplayerModernRewindButtonFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/widget/ImageView;", + parameters = listOf(), + literalSupplier = { MiniplayerResourcePatch.modernMiniplayerRewindButton } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernViewParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernViewParentFingerprint.kt new file mode 100644 index 00000000..a6baeec7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerModernViewParentFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object MiniplayerModernViewParentFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Ljava/lang/String;", + parameters = listOf(), + strings = listOf("player_overlay_modern_mini_player_controls") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideFingerprint.kt similarity index 68% rename from src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideFingerprint.kt index 9e80c81a..9d9bf5e1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideFingerprint.kt @@ -1,10 +1,10 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints +package app.revanced.patches.youtube.layout.miniplayer.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal object MiniPlayerOverrideFingerprint : MethodFingerprint( +internal object MiniplayerOverrideFingerprint : MethodFingerprint( returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L"), diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideNoContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideNoContextFingerprint.kt new file mode 100644 index 00000000..53900f99 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerOverrideNoContextFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object MiniplayerOverrideNoContextFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, + returnType = "Z", + opcodes = listOf(Opcode.IGET_BOOLEAN), // anchor to insert the instruction +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerResponseModelSizeCheckFingerprint.kt similarity index 56% rename from src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerResponseModelSizeCheckFingerprint.kt index 4ac508ed..b25e727c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/MiniplayerResponseModelSizeCheckFingerprint.kt @@ -1,15 +1,15 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints +package app.revanced.patches.youtube.layout.miniplayer.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint( - "L", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("Ljava/lang/Object;", "Ljava/lang/Object;"), - listOf( +internal object MiniplayerResponseModelSizeCheckFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "L", + parameters = listOf("Ljava/lang/Object;", "Ljava/lang/Object;"), + opcodes = listOf( Opcode.RETURN_OBJECT, Opcode.CHECK_CAST, Opcode.CHECK_CAST, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/YouTubePlayerOverlaysLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/YouTubePlayerOverlaysLayoutFingerprint.kt new file mode 100644 index 00000000..c53a208e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/fingerprints/YouTubePlayerOverlaysLayoutFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.miniplayer.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patches.youtube.layout.miniplayer.fingerprints.YouTubePlayerOverlaysLayoutFingerprint.YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME + +internal object YouTubePlayerOverlaysLayoutFingerprint : MethodFingerprint( + customFingerprint = { _, classDef -> + classDef.type == YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME + } +) { + const val YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME = + "Lcom/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout;" +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt index fd00bf39..f64d7d76 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt @@ -1,7 +1,5 @@ package app.revanced.patches.youtube.layout.player.overlay -import app.revanced.util.exception -import app.revanced.util.indexOfFirstWideLiteralInstructionValue import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -9,6 +7,8 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.youtube.layout.player.overlay.fingerprints.CreatePlayerOverviewFingerprint +import app.revanced.util.exception +import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( @@ -27,7 +27,7 @@ object CustomPlayerOverlayOpacityPatch : BytecodePatch(setOf(CreatePlayerOvervie CreatePlayerOverviewFingerprint.result?.let { result -> result.mutableMethod.apply { val viewRegisterIndex = - indexOfFirstWideLiteralInstructionValue(CustomPlayerOverlayOpacityResourcePatch.scrimOverlayId) + 3 + indexOfFirstWideLiteralInstructionValueOrThrow(CustomPlayerOverlayOpacityResourcePatch.scrimOverlayId) + 3 val viewRegister = getInstruction(viewRegisterIndex).registerA diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorBytecodePatch.kt index 98acf716..08d3fa02 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorBytecodePatch.kt @@ -1,7 +1,5 @@ package app.revanced.patches.youtube.layout.seekbar -import app.revanced.util.exception -import app.revanced.util.indexOfFirstWideLiteralInstructionValue import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -15,6 +13,8 @@ import app.revanced.patches.youtube.layout.seekbar.fingerprints.ShortsSeekbarCol import app.revanced.patches.youtube.layout.theme.LithoColorHookPatch import app.revanced.patches.youtube.layout.theme.LithoColorHookPatch.lithoColorOverrideHook import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.util.exception +import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @@ -30,7 +30,7 @@ internal object SeekbarColorBytecodePatch : BytecodePatch( override fun execute(context: BytecodeContext) { fun MutableMethod.addColorChangeInstructions(resourceId: Long) { - val registerIndex = indexOfFirstWideLiteralInstructionValue(resourceId) + 2 + val registerIndex = indexOfFirstWideLiteralInstructionValueOrThrow(resourceId) + 2 val colorRegister = getInstruction(registerIndex).registerA addInstructions( registerIndex + 1, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt index f09c7d69..8b41fc5d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt @@ -13,18 +13,51 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.layout.tablet.fingerprints.GetFormFactorFingerprint import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.util.exception +import app.revanced.util.resultOrThrow @Patch( name = "Enable tablet layout", - description = "Adds an option to spoof the device form factor to a tablet which enables the tablet layout.", - dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], - compatiblePackages = [CompatiblePackage("com.google.android.youtube")] + description = "Adds an option to enable tablet layout", + dependencies = [ + IntegrationsPatch::class, + SettingsPatch::class, + AddResourcesPatch::class, + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", arrayOf( + "18.32.39", + "18.37.36", + "18.38.44", + "18.43.45", + "18.44.41", + "18.45.43", + "18.48.39", + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.38", + "19.10.39", + "19.11.43", + "19.12.41", + "19.13.37", + "19.14.43", + "19.15.36", + "19.16.39" + ) + ) + ] ) @Suppress("unused") -object EnableTabletLayoutPatch : BytecodePatch( - setOf(GetFormFactorFingerprint) -) { +object EnableTabletLayoutPatch : BytecodePatch(setOf(GetFormFactorFingerprint)) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/TabletLayoutPatch;" + override fun execute(context: BytecodeContext) { AddResourcesPatch(this::class) @@ -32,7 +65,7 @@ object EnableTabletLayoutPatch : BytecodePatch( SwitchPreference("revanced_tablet_layout") ) - GetFormFactorFingerprint.result?.let { + GetFormFactorFingerprint.resultOrThrow().let { it.mutableMethod.apply { val returnIsLargeFormFactorIndex = getInstructions().lastIndex - 4 val returnIsLargeFormFactorLabel = getInstruction(returnIsLargeFormFactorIndex) @@ -40,8 +73,8 @@ object EnableTabletLayoutPatch : BytecodePatch( addInstructionsWithLabels( 0, """ - invoke-static { }, Lapp/revanced/integrations/youtube/patches/EnableTabletLayoutPatch;->enableTabletLayout()Z - move-result v0 # Free register + invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->getTabletLayoutEnabled()Z + move-result v0 if-nez v0, :is_large_form_factor """, ExternalLabel( @@ -50,6 +83,6 @@ object EnableTabletLayoutPatch : BytecodePatch( ) ) } - } ?: GetFormFactorFingerprint.exception + } } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/fingerprints/GetFormFactorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/fingerprints/GetFormFactorFingerprint.kt index c7cb6d1e..8742fe5b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/fingerprints/GetFormFactorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/fingerprints/GetFormFactorFingerprint.kt @@ -21,5 +21,6 @@ internal object GetFormFactorFingerprint : MethodFingerprint( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, Opcode.RETURN_OBJECT - ) + ), + strings = listOf("") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt index d3b4183a..6b1f154b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt @@ -1,152 +1,11 @@ package app.revanced.patches.youtube.layout.tabletminiplayer import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.all.misc.resources.AddResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorParentFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint -import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.util.exception -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import app.revanced.patches.youtube.layout.miniplayer.MiniplayerPatch -@Patch( - name = "Tablet mini player", - description = "Adds an option to enable the tablet mini player layout.", - dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], - compatiblePackages = [ - CompatiblePackage( - "com.google.android.youtube", arrayOf( - "18.32.39", - "18.37.36", - "18.38.44", - "18.43.45", - "18.44.41", - "18.45.43", - "18.48.39", - "18.49.37", - "19.01.34", - "19.02.39", - "19.03.36", - "19.04.38", - "19.05.36", - "19.06.39", - "19.07.40", - "19.08.36", - "19.09.38", - "19.10.39", - "19.11.43", - "19.12.41", - "19.13.37", - "19.14.43", - "19.15.36", - "19.16.39", - ) - ) - ] -) -@Suppress("unused") -object TabletMiniPlayerPatch : BytecodePatch( - setOf( - MiniPlayerDimensionsCalculatorParentFingerprint, - MiniPlayerResponseModelSizeCheckFingerprint, - MiniPlayerOverrideFingerprint - ) -) { +@Deprecated("This patch class has been renamed to Miniplayer.") +object TabletMiniPlayerPatch : BytecodePatch(dependencies = setOf(MiniplayerPatch::class)) { override fun execute(context: BytecodeContext) { - AddResourcesPatch(this::class) - - SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( - SwitchPreference("revanced_tablet_miniplayer") - ) - - // First resolve the fingerprints via the parent fingerprint. - MiniPlayerDimensionsCalculatorParentFingerprint.result - ?: throw MiniPlayerDimensionsCalculatorParentFingerprint.exception - val miniPlayerClass = MiniPlayerDimensionsCalculatorParentFingerprint.result!!.classDef - - /* - * No context parameter method. - */ - MiniPlayerOverrideNoContextFingerprint.resolve(context, miniPlayerClass) - val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall() - - // Insert right before the return instruction. - val secondInsertIndex = method.implementation!!.instructions.size - 1 - method.insertOverride( - secondInsertIndex, parameterRegister - /** same register used to return **/ - ) - - /* - * Override every return instruction with the proxy call. - */ - MiniPlayerOverrideFingerprint.result?.let { result -> - result.mutableMethod.let { method -> - val appNameStringIndex = result.scanResult.stringsScanResult!!.matches.first().index + 2 - context.toMethodWalker(method).nextMethod(appNameStringIndex, true) - .getMethod() as MutableMethod - }.apply { - implementation!!.let { implementation -> - val returnIndices = implementation.instructions - .withIndex() - .filter { (_, instruction) -> instruction.opcode == Opcode.RETURN } - .map { (index, _) -> index } - - if (returnIndices.isEmpty()) throw PatchException("No return instructions found.") - - // This method clobbers register p0 to return the value, calculate to override. - val returnedRegister = implementation.registerCount - parameters.size - - // Hook the returned register on every return instruction. - returnIndices.forEach { index -> insertOverride(index, returnedRegister) } - } - } - - return@let - } ?: throw MiniPlayerOverrideFingerprint.exception - - /* - * Size check return value override. - */ - MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall() - } - - // Helper methods. - private fun MethodFingerprint.addProxyCall(): Triple { - val (method, scanIndex, parameterRegister) = this.unwrap() - method.insertOverride(scanIndex, parameterRegister) - - return Triple(method, scanIndex, parameterRegister) - } - - private fun MutableMethod.insertOverride(index: Int, overrideRegister: Int) { - this.addInstructions( - index, - """ - invoke-static {v$overrideRegister}, Lapp/revanced/integrations/youtube/patches/TabletMiniPlayerOverridePatch;->getTabletMiniPlayerOverride(Z)Z - move-result v$overrideRegister - """ - ) - } - - private fun MethodFingerprint.unwrap(): Triple { - val result = this.result!! - val scanIndex = result.scanResult.patternScanResult!!.endIndex - val method = result.mutableMethod - val instructions = method.implementation!!.instructions - val parameterRegister = (instructions[scanIndex] as OneRegisterInstruction).registerA - - return Triple(method, scanIndex, parameterRegister) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt deleted file mode 100644 index 2e161237..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "V", - parameters = listOf("F"), - opcodes = listOf( - Opcode.CONST_HIGH16, - Opcode.ADD_FLOAT_2ADDR, - null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.FLOAT_TO_INT, - Opcode.INVOKE_INTERFACE, - Opcode.RETURN_VOID, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt deleted file mode 100644 index c6ea61f3..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint( - "Z", AccessFlags.FINAL or AccessFlags.PRIVATE, - opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt index 3e9bfd60..23d7a62f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt @@ -16,7 +16,7 @@ import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoading import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.util.exception -import app.revanced.util.indexOfFirstWideLiteralInstructionValue +import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -123,7 +123,7 @@ object ThemeBytecodePatch : BytecodePatch( ) UseGradientLoadingScreenFingerprint.result?.mutableMethod?.apply { - val isEnabledIndex = indexOfFirstWideLiteralInstructionValue(GRADIENT_LOADING_SCREEN_AB_CONSTANT) + 3 + val isEnabledIndex = indexOfFirstWideLiteralInstructionValueOrThrow(GRADIENT_LOADING_SCREEN_AB_CONSTANT) + 3 val isEnabledRegister = getInstruction(isEnabledIndex - 1).registerA addInstructions( diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt index c008f673..de699484 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt @@ -286,9 +286,12 @@ object SpoofClientPatch : BytecodePatch( // Fix playback speed menu item if spoofing to iOS. CreatePlaybackSpeedMenuItemFingerprint.resultOrThrow().let { - val shouldCreateMenuIndex = it.scanResult.patternScanResult!!.endIndex + val scanResult = it.scanResult.patternScanResult!! + if (scanResult.startIndex != 0) throw PatchException("Unexpected start index: ${scanResult.startIndex}") it.mutableMethod.apply { + // Find the conditional check if the playback speed menu item is not created. + val shouldCreateMenuIndex = indexOfFirstInstructionOrThrow(scanResult.endIndex) { opcode == Opcode.IF_EQZ } val shouldCreateMenuRegister = getInstruction(shouldCreateMenuIndex).registerA addInstructions( diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt index 389977dd..035771ce 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt @@ -8,15 +8,27 @@ import com.android.tools.smali.dexlib2.Opcode internal object CreatePlaybackSpeedMenuItemFingerprint : MethodFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "V", - parameters = listOf("[L", "F"), opcodes = listOf( - Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, // First instruction of the method Opcode.IGET_OBJECT, Opcode.IGET_OBJECT, Opcode.CONST_4, Opcode.IF_EQZ, Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, // Return value controls the creation of the playback speed menu item. - Opcode.IF_EQZ, // If the return value is false, the playback speed menu item is not created. + null // MOVE_RESULT or MOVE_RESULT_OBJECT, Return value controls the creation of the playback speed menu item. ), + // 19.01 and earlier is missing the second parameter. + // Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures. + customFingerprint = custom@{ methodDef, _ -> + // 19.01 and earlier parameters are: "[L" + // 19.02+ parameters are "[L", "F" + val parameterTypes = methodDef.parameterTypes + val firstParameter = parameterTypes.firstOrNull() + + if (firstParameter == null || !firstParameter.startsWith("[L")) { + return@custom false + } + + parameterTypes.size == 1 || (parameterTypes.size == 2 && parameterTypes[1] == "F") + } ) diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index acc989c3..7e5388d3 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -8,6 +8,7 @@ import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @@ -99,6 +100,7 @@ fun Method.indexOfIdResourceOrThrow(resourceName: String): Int { * Find the index of the first wide literal instruction with the given value. * * @return the first literal instruction with the value, or -1 if not found. + * @see indexOfFirstWideLiteralInstructionValueOrThrow */ fun Method.indexOfFirstWideLiteralInstructionValue(literal: Long) = implementation?.let { it.instructions.indexOfFirst { instruction -> @@ -106,6 +108,18 @@ fun Method.indexOfFirstWideLiteralInstructionValue(literal: Long) = implementati } } ?: -1 +/** + * Find the index of the first wide literal instruction with the given value, + * or throw an exception if not found. + * + * @return the first literal instruction with the value, or throws [PatchException] if not found. + */ +fun Method.indexOfFirstWideLiteralInstructionValueOrThrow(literal: Long) : Int { + val index = indexOfFirstWideLiteralInstructionValue(literal) + if (index < 0) throw PatchException("Could not find literal value: $literal") + return index +} + /** * Check if the method contains a literal with the given value. * @@ -144,7 +158,9 @@ inline fun Instruction.getReference() = (this as? Refere * @return The index of the first [Instruction] that matches the predicate. */ // TODO: delete this on next major release, the overloaded method with an optional start index serves the same purposes. -@Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)")) +// Method is deprecated, but annotation is commented out otherwise during compilation usage of the replacement is +// incorrectly flagged as deprecated. +//@Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)")) fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = indexOfFirstInstruction(0, predicate) /** @@ -179,6 +195,21 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, predicate: Instru return index } +/** + * @return The list of indices of the opcode in reverse order. + */ +fun Method.findOpcodeIndicesReversed(opcode: Opcode): List { + val indexes = implementation!!.instructions + .withIndex() + .filter { (_, instruction) -> instruction.opcode == opcode } + .map { (index, _) -> index } + .reversed() + + if (indexes.isEmpty()) throw PatchException("No ${opcode.name} instructions found in: $this") + + return indexes +} + /** * Return the resolved methods of [MethodFingerprint]s early. */ diff --git a/src/main/resources/addresources/values/arrays.xml b/src/main/resources/addresources/values/arrays.xml index 5fad2d88..f8f2b421 100644 --- a/src/main/resources/addresources/values/arrays.xml +++ b/src/main/resources/addresources/values/arrays.xml @@ -16,6 +16,35 @@ 17.33.42 + + + @string/revanced_miniplayer_type_entry_1 + @string/revanced_miniplayer_type_entry_2 + @string/revanced_miniplayer_type_entry_3 + @string/revanced_miniplayer_type_entry_4 + @string/revanced_miniplayer_type_entry_5 + @string/revanced_miniplayer_type_entry_6 + + + + ORIGINAL + PHONE + TABLET + MODERN_1 + MODERN_2 + MODERN_3 + + + @string/revanced_miniplayer_type_entry_1 + @string/revanced_miniplayer_type_entry_2 + @string/revanced_miniplayer_type_entry_3 + + + ORIGINAL + PHONE + TABLET + + @string/revanced_start_page_entry_0 diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index b4506ea3..774198db 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -661,6 +661,7 @@ Player overlay opacity Opacity value between 0-100, where 0 is transparent + Player overlay opacity must be between 0-100 Return YouTube Dislike @@ -947,11 +948,29 @@ Tablet layout is enabled Tablet layout is disabled Community posts do not show up on tablet layouts - - - Enable tablet mini player - Mini player is enabled - Mini player is disabled + x + + Miniplayer + Change the style of the in app minimized player + Miniplayer type + Original + Phone + Tablet + Modern 1 + Modern 2 + Modern 3 + Hide expand and close buttons + Buttons are hidden\n(swipe miniplayer to expand or close) + Expand and close buttons are shown + Hide subtexts + Subtexts are hidden + Subtexts are shown + Hide skip forward and back buttons + Skip forward and back are hidden + Skip forward and back are shown + Overlay opacity + Opacity value between 0-100, where 0 is transparent + Miniplayer overlay opacity must be between 0-100 Enable gradient loading screen From 66ccdbddd4fcec6a3d272d4679a150693f94e6d7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 7 Jun 2024 22:50:16 +0000 Subject: [PATCH 04/23] chore(release): 4.10.0-dev.1 [skip ci] # [4.10.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.9.0...v4.10.0-dev.1) (2024-06-07) ### Features * **YouTube - Miniplayer:** Rename `Tablet mini player` and allow selecting the style of the in-app miniplayer ([#3302](https://github.com/ReVanced/revanced-patches/issues/3302)) ([5511736](https://github.com/ReVanced/revanced-patches/commit/5511736b0c5dd409db6a68db0f85e389bb95be47)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0ecf944..7af67693 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.9.0...v4.10.0-dev.1) (2024-06-07) + + +### Features + +* **YouTube - Miniplayer:** Rename `Tablet mini player` and allow selecting the style of the in-app miniplayer ([#3302](https://github.com/ReVanced/revanced-patches/issues/3302)) ([5511736](https://github.com/ReVanced/revanced-patches/commit/5511736b0c5dd409db6a68db0f85e389bb95be47)) + # [4.9.0](https://github.com/ReVanced/revanced-patches/compare/v4.8.3...v4.9.0) (2024-06-02) diff --git a/gradle.properties b/gradle.properties index 592a6147..3bfe98e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.9.0 +version = 4.10.0-dev.1 From 37d415b53af4771d9c97a8b1c153be32bf3ac2e0 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 8 Jun 2024 11:35:20 +0300 Subject: [PATCH 05/23] fix(YouTube): Rename `Minimized playback` to `Remove background playback restrictions` (#3314) --- api/revanced-patches.api | 6 + .../BackgroundPlaybackPatch.kt | 112 +++++++++++++++++ .../BackgroundPlaybackResourcePatch.kt} | 4 +- .../BackgroundPlaybackManagerFingerprint.kt} | 4 +- .../BackgroundPlaybackSettingsFingerprint.kt} | 8 +- ...undPlaybackPolicyControllerFingerprint.kt} | 13 +- .../MinimizedPlaybackPatch.kt | 114 +----------------- .../resources/addresources/values/strings.xml | 6 +- 8 files changed, 137 insertions(+), 130 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt rename src/main/kotlin/app/revanced/patches/youtube/misc/{minimizedplayback/MinimizedPlaybackResourcePatch.kt => backgroundplayback/BackgroundPlaybackResourcePatch.kt} (80%) rename src/main/kotlin/app/revanced/patches/youtube/misc/{minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt => backgroundplayback/fingerprints/BackgroundPlaybackManagerFingerprint.kt} (85%) rename src/main/kotlin/app/revanced/patches/youtube/misc/{minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt => backgroundplayback/fingerprints/BackgroundPlaybackSettingsFingerprint.kt} (61%) rename src/main/kotlin/app/revanced/patches/youtube/misc/{minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt => backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt} (57%) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 9f253870..4b276044 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1638,6 +1638,12 @@ public final class app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/youtube/misc/debugging/DebuggingPatch : app/revanced/patcher/patch/ResourcePatch { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/debugging/DebuggingPatch; public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt new file mode 100644 index 00000000..9cad7fd4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -0,0 +1,112 @@ +package app.revanced.patches.youtube.misc.backgroundplayback + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.backgroundplayback.fingerprints.KidsBackgroundPlaybackPolicyControllerFingerprint +import app.revanced.patches.youtube.misc.backgroundplayback.fingerprints.BackgroundPlaybackManagerFingerprint +import app.revanced.patches.youtube.misc.backgroundplayback.fingerprints.BackgroundPlaybackSettingsFingerprint +import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch +import app.revanced.patches.youtube.video.information.VideoInformationPatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +@Patch( + name = "Remove background playback restrictions", + description = "Removes restrictions on background playback, including playing kids videos in the background.", + dependencies = [ + BackgroundPlaybackResourcePatch::class, + IntegrationsPatch::class, + PlayerTypeHookPatch::class, + VideoInformationPatch::class, + SettingsPatch::class, + AddResourcesPatch::class + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.48.39", + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.38", + "19.10.39", + "19.11.43", + "19.12.41", + "19.13.37", + "19.14.43", + "19.15.36", + "19.16.39", + ] + ) + ] +) +@Suppress("unused") +object BackgroundPlaybackPatch : BytecodePatch( + setOf( + BackgroundPlaybackManagerFingerprint, + BackgroundPlaybackSettingsFingerprint, + KidsBackgroundPlaybackPolicyControllerFingerprint + ) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/patches/BackgroundPlaybackPatch;" + + override fun execute(context: BytecodeContext) { + AddResourcesPatch(this::class) + + SettingsPatch.PreferenceScreen.MISC.addPreferences( + NonInteractivePreference("revanced_background_playback") + ) + + BackgroundPlaybackManagerFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, + """ + invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackIsNotShort()Z + move-result v0 + return v0 + """ + ) + + // Enable background playback option in YouTube settings + BackgroundPlaybackSettingsFingerprint.resultOrThrow().mutableMethod.apply { + val booleanCalls = implementation!!.instructions.withIndex() + .filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" } + + val settingsBooleanIndex = booleanCalls.elementAt(1).index + val settingsBooleanMethod = + context.toMethodWalker(this).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod + + settingsBooleanMethod.addInstructions( + 0, + """ + invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideBackgroundPlaybackAvailable()Z + move-result v0 + return v0 + """ + ) + } + + // Force allowing background play for videos labeled for kids. + KidsBackgroundPlaybackPolicyControllerFingerprint.resultOrThrow().mutableMethod.addInstruction( + 0, + "return-void" + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackResourcePatch.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackResourcePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackResourcePatch.kt index d310d3ab..3be877a9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackResourcePatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.minimizedplayback +package app.revanced.patches.youtube.misc.backgroundplayback import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch @@ -8,7 +8,7 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch @Patch( dependencies = [ResourceMappingPatch::class], ) -internal object MinimizedPlaybackResourcePatch : ResourcePatch() { +internal object BackgroundPlaybackResourcePatch : ResourcePatch() { internal var prefBackgroundAndOfflineCategoryId: Long = -1 override fun execute(context: ResourceContext) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackManagerFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackManagerFingerprint.kt index 2be2ec0d..4695df5d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackManagerFingerprint.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints +package app.revanced.patches.youtube.misc.backgroundplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint( +internal object BackgroundPlaybackManagerFingerprint : MethodFingerprint( "Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackSettingsFingerprint.kt similarity index 61% rename from src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackSettingsFingerprint.kt index 8f31e017..c57d9173 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/BackgroundPlaybackSettingsFingerprint.kt @@ -1,12 +1,12 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints +package app.revanced.patches.youtube.misc.backgroundplayback.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.misc.minimizedplayback.MinimizedPlaybackResourcePatch +import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackResourcePatch import app.revanced.util.patch.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object MinimizedPlaybackSettingsFingerprint : LiteralValueFingerprint( +internal object BackgroundPlaybackSettingsFingerprint : LiteralValueFingerprint( returnType = "Ljava/lang/String;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf(), @@ -19,5 +19,5 @@ internal object MinimizedPlaybackSettingsFingerprint : LiteralValueFingerprint( Opcode.IF_NEZ, Opcode.GOTO ), - literalSupplier = { MinimizedPlaybackResourcePatch.prefBackgroundAndOfflineCategoryId } + literalSupplier = { BackgroundPlaybackResourcePatch.prefBackgroundAndOfflineCategoryId } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt similarity index 57% rename from src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt index af992d60..7f33326c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt @@ -1,12 +1,11 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints +package app.revanced.patches.youtube.misc.backgroundplayback.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.util.patch.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction -internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( +internal object KidsBackgroundPlaybackPolicyControllerFingerprint : LiteralValueFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("I", "L", "L"), @@ -26,9 +25,5 @@ internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerp Opcode.INVOKE_VIRTUAL, Opcode.RETURN_VOID ), - customFingerprint = { methodDef, _ -> - methodDef.implementation!!.instructions.any { - ((it as? NarrowLiteralInstruction)?.narrowLiteral == 5) - } - } + literalSupplier = { 5 }, ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt index c3569590..b354a6bc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt @@ -1,117 +1,11 @@ package app.revanced.patches.youtube.misc.minimizedplayback import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.all.misc.resources.AddResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference -import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint -import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch -import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.util.exception -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -@Patch( - name = "Minimized playback", - description = "Unlocks options for picture-in-picture and background playback.", - dependencies = [ - MinimizedPlaybackResourcePatch::class, - IntegrationsPatch::class, - PlayerTypeHookPatch::class, - VideoInformationPatch::class, - SettingsPatch::class, - AddResourcesPatch::class - ], - compatiblePackages = [ - CompatiblePackage( - "com.google.android.youtube", - [ - "18.48.39", - "18.49.37", - "19.01.34", - "19.02.39", - "19.03.36", - "19.04.38", - "19.05.36", - "19.06.39", - "19.07.40", - "19.08.36", - "19.09.38", - "19.10.39", - "19.11.43", - "19.12.41", - "19.13.37", - "19.14.43", - "19.15.36", - "19.16.39", - ] - ) - ] -) -@Suppress("unused") -object MinimizedPlaybackPatch : BytecodePatch( - setOf( - MinimizedPlaybackManagerFingerprint, - MinimizedPlaybackSettingsFingerprint, - KidsMinimizedPlaybackPolicyControllerFingerprint - ) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/youtube/patches/MinimizedPlaybackPatch;" +import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch +@Deprecated("This patch class has been renamed to BackgroundPlaybackPatch.") +object MinimizedPlaybackPatch : BytecodePatch(dependencies = setOf(BackgroundPlaybackPatch::class)) { override fun execute(context: BytecodeContext) { - AddResourcesPatch(this::class) - - SettingsPatch.PreferenceScreen.MISC.addPreferences( - NonInteractivePreference("revanced_minimized_playback") - ) - - MinimizedPlaybackManagerFingerprint.result?.apply { - mutableMethod.addInstructions( - 0, - """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->playbackIsNotShort()Z - move-result v0 - return v0 - """ - ) - } ?: throw MinimizedPlaybackManagerFingerprint.exception - - // Enable minimized playback option in YouTube settings - MinimizedPlaybackSettingsFingerprint.result?.apply { - val booleanCalls = method.implementation!!.instructions.withIndex() - .filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" } - - val settingsBooleanIndex = booleanCalls.elementAt(1).index - val settingsBooleanMethod = - context.toMethodWalker(method).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod - - settingsBooleanMethod.addInstructions( - 0, - """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideMinimizedPlaybackAvailable()Z - move-result v0 - return v0 - """ - ) - } ?: throw MinimizedPlaybackSettingsFingerprint.exception - - // Force allowing background play for videos labeled for kids. - // Some regions and YouTube accounts do not require this patch. - KidsMinimizedPlaybackPolicyControllerFingerprint.result?.apply { - mutableMethod.addInstruction( - 0, - "return-void" - ) - } ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception } -} +} \ No newline at end of file diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 774198db..1a85eafc 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -1051,9 +1051,9 @@ Opening links externally Opening links in app - - Minimized playback - This setting can be found in Settings -> Background + + Background playback + This setting can be found in Settings -> Background Remove tracking query parameter From 3c31e55b13d9495e857f068f8cd2b4320112d763 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 8 Jun 2024 11:35:44 +0300 Subject: [PATCH 06/23] fix(YouTube Music): Rename `Minimized playback` to `Remove background playback restrictions` (#3315) --- api/revanced-patches.api | 6 +++ .../MinimizedPlaybackPatch.kt | 45 ++--------------- .../BackgroundPlaybackPatch.kt | 50 +++++++++++++++++++ .../BackgroundPlaybackDisableFingerprint.kt | 2 +- ...undPlaybackPolicyControllerFingerprint.kt} | 4 +- .../backgroundplay/BackgroundPlayPatch.kt | 7 +-- 6 files changed, 67 insertions(+), 47 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt rename src/main/kotlin/app/revanced/patches/music/{layout/minimizedplayback => misc/backgroundplayback}/fingerprints/BackgroundPlaybackDisableFingerprint.kt (88%) rename src/main/kotlin/app/revanced/patches/music/{layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt => misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt} (78%) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 4b276044..e0a49a1e 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -403,6 +403,12 @@ public final class app/revanced/patches/music/misc/androidauto/BypassCertificate public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/music/misc/gms/Constants { public static final field INSTANCE Lapp/revanced/patches/music/misc/gms/Constants; } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt index 918e08f2..8d497d9b 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt @@ -1,50 +1,13 @@ package app.revanced.patches.music.layout.minimizedplayback import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.music.layout.minimizedplayback.fingerprints.BackgroundPlaybackDisableFingerprint -import app.revanced.patches.music.layout.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint -import app.revanced.util.exception +import app.revanced.patches.music.misc.backgroundplayback.BackgroundPlaybackPatch -@Patch( - name = "Minimized playback", - description = "Unlocks options for picture-in-picture and background playback.", - compatiblePackages = [ - CompatiblePackage( - "com.google.android.apps.youtube.music", - [ - "6.45.54", - "6.51.53", - "7.01.53", - "7.02.52", - "7.03.52", - ] - ) - ] -) -@Suppress("unused") +@Deprecated("This patch has been merged into BackgroundPlaybackPatch.") object MinimizedPlaybackPatch : BytecodePatch( - setOf( - KidsMinimizedPlaybackPolicyControllerFingerprint, - BackgroundPlaybackDisableFingerprint, - ), + dependencies = setOf(BackgroundPlaybackPatch::class), ) { override fun execute(context: BytecodeContext) { - KidsMinimizedPlaybackPolicyControllerFingerprint.result?.mutableMethod?.addInstruction( - 0, - "return-void", - ) ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception - - BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """, - ) ?: throw BackgroundPlaybackDisableFingerprint.exception } -} +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt new file mode 100644 index 00000000..51608bc5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -0,0 +1,50 @@ +package app.revanced.patches.music.misc.backgroundplayback + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.music.misc.backgroundplayback.fingerprints.BackgroundPlaybackDisableFingerprint +import app.revanced.patches.music.misc.backgroundplayback.fingerprints.KidsBackgroundPlaybackPolicyControllerFingerprint +import app.revanced.util.resultOrThrow + +@Patch( + name = "Remove background playback restrictions", + description = "Removes restrictions on background playback.", + compatiblePackages = [ + CompatiblePackage( + "com.google.android.apps.youtube.music", + [ + "6.45.54", + "6.51.53", + "7.01.53", + "7.02.52", + "7.03.52", + ] + ) + ] +) +@Suppress("unused") +object BackgroundPlaybackPatch : BytecodePatch( + setOf( + KidsBackgroundPlaybackPolicyControllerFingerprint, + BackgroundPlaybackDisableFingerprint, + ), +) { + override fun execute(context: BytecodeContext) { + KidsBackgroundPlaybackPolicyControllerFingerprint.resultOrThrow().mutableMethod.addInstruction( + 0, + "return-void", + ) + + BackgroundPlaybackDisableFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """, + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt index d1341028..bf5f2119 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.layout.minimizedplayback.fingerprints +package app.revanced.patches.music.misc.backgroundplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt similarity index 78% rename from src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt index da6823c8..45374d40 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/fingerprints/KidsBackgroundPlaybackPolicyControllerFingerprint.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.music.layout.minimizedplayback.fingerprints +package app.revanced.patches.music.misc.backgroundplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( +internal object KidsBackgroundPlaybackPolicyControllerFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("I", "L", "Z"), diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt index a17903a2..da245e89 100644 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt @@ -2,10 +2,11 @@ package app.revanced.patches.music.premium.backgroundplay import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patches.music.layout.minimizedplayback.MinimizedPlaybackPatch -@Deprecated("This patch has been merged into MinimizedPlaybackPatch.") +import app.revanced.patches.music.misc.backgroundplayback.BackgroundPlaybackPatch + +@Deprecated("This patch has been merged into BackgroundPlaybackPatch.") object BackgroundPlayPatch : BytecodePatch( - dependencies = setOf(MinimizedPlaybackPatch::class), + dependencies = setOf(BackgroundPlaybackPatch::class), ) { override fun execute(context: BytecodeContext) { } From 2f252aad38a86e59da050a0644143012ba868b43 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 8 Jun 2024 08:37:57 +0000 Subject: [PATCH 07/23] chore(release): 4.10.0-dev.2 [skip ci] # [4.10.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.1...v4.10.0-dev.2) (2024-06-08) ### Bug Fixes * **YouTube Music:** Rename `Minimized playback` to `Remove background playback restrictions` ([#3315](https://github.com/ReVanced/revanced-patches/issues/3315)) ([3c31e55](https://github.com/ReVanced/revanced-patches/commit/3c31e55b13d9495e857f068f8cd2b4320112d763)) * **YouTube:** Rename `Minimized playback` to `Remove background playback restrictions` ([#3314](https://github.com/ReVanced/revanced-patches/issues/3314)) ([37d415b](https://github.com/ReVanced/revanced-patches/commit/37d415b53af4771d9c97a8b1c153be32bf3ac2e0)) --- CHANGELOG.md | 8 ++++++++ gradle.properties | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7af67693..930d20dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# [4.10.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.1...v4.10.0-dev.2) (2024-06-08) + + +### Bug Fixes + +* **YouTube Music:** Rename `Minimized playback` to `Remove background playback restrictions` ([#3315](https://github.com/ReVanced/revanced-patches/issues/3315)) ([3c31e55](https://github.com/ReVanced/revanced-patches/commit/3c31e55b13d9495e857f068f8cd2b4320112d763)) +* **YouTube:** Rename `Minimized playback` to `Remove background playback restrictions` ([#3314](https://github.com/ReVanced/revanced-patches/issues/3314)) ([37d415b](https://github.com/ReVanced/revanced-patches/commit/37d415b53af4771d9c97a8b1c153be32bf3ac2e0)) + # [4.10.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.9.0...v4.10.0-dev.1) (2024-06-07) diff --git a/gradle.properties b/gradle.properties index 3bfe98e3..d97c7ab7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.1 +version = 4.10.0-dev.2 From 5fa9fd2dfef43838d7311a967a3e805256a5d116 Mon Sep 17 00:00:00 2001 From: Yan <15308404+OctoNezd@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:31:18 +0300 Subject: [PATCH 08/23] feat(Boost For Reddit): Add `Fix /s/ links` patch (#3154) Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 28 ++++++++- .../customclients/BaseFixSLinksPatch.kt | 49 +++++++++++++++ .../fix/slink/FixSLinksPatch.kt | 44 +++++++++++++ .../GetOAuthAccessTokenFingerprint.kt | 10 +++ .../HandleNavigationFingerprint.kt | 12 ++++ .../misc/integrations/IntegrationsPatch.kt | 10 +++ .../fingerprints/InitFingerprint.kt | 10 +++ .../syncforreddit/fix/slink/FixSLinksPatch.kt | 63 ++++++++++++------- .../SetAuthorizationHeaderFingerprint.kt | 9 +++ .../misc.integrations/IntegrationsPatch.kt | 10 +++ .../fingerprints/InitFingerprint.kt | 10 +++ 11 files changed, 229 insertions(+), 26 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/BaseFixSLinksPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/GetOAuthAccessTokenFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/HandleNavigationFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/fingerprints/InitFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/fingerprints/SetAuthorizationHeaderFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/IntegrationsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/fingerprints/InitFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index e0a49a1e..5b4d8681 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -535,6 +535,18 @@ public final class app/revanced/patches/reddit/ad/general/HideAdsPatch : app/rev public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public abstract class app/revanced/patches/reddit/customclients/BaseFixSLinksPatch : app/revanced/patcher/patch/BytecodePatch { + public fun (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Ljava/util/Set;)V + public synthetic fun (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + protected abstract fun getIntegrationsClassDescriptor ()Ljava/lang/String; + protected final fun getResolveSLinkMethod ()Ljava/lang/String; + protected final fun getSetAccessTokenMethod ()Ljava/lang/String; + protected abstract fun patchNavigationHandler (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V + protected abstract fun patchSetAccessToken (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V +} + public abstract class app/revanced/patches/reddit/customclients/BaseSpoofClientPatch : app/revanced/patcher/patch/BytecodePatch { public fun (Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V public synthetic fun (Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -570,6 +582,14 @@ public final class app/revanced/patches/reddit/customclients/boostforreddit/api/ public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V } +public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch; +} + +public final class app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch; +} + public final class app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch; public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V @@ -648,10 +668,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/detec public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patcher/patch/BytecodePatch { +public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + +public final class app/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch; } public final class app/revanced/patches/reddit/layout/disablescreenshotpopup/DisableScreenshotPopupPatch : app/revanced/patcher/patch/BytecodePatch { diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/BaseFixSLinksPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/BaseFixSLinksPatch.kt new file mode 100644 index 00000000..bc7b4ee3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/BaseFixSLinksPatch.kt @@ -0,0 +1,49 @@ +package app.revanced.patches.reddit.customclients + +import app.revanced.patcher.PatchClass +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.fingerprint.MethodFingerprintResult +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.util.resultOrThrow + +abstract class BaseFixSLinksPatch( + private val handleNavigationFingerprint: MethodFingerprint, + private val setAccessTokenFingerprint: MethodFingerprint, + compatiblePackages: Set, + dependencies: Set = emptySet(), +) : BytecodePatch( + name = "Fix /s/ links", + fingerprints = setOf(handleNavigationFingerprint, setAccessTokenFingerprint), + compatiblePackages = compatiblePackages, + dependencies = dependencies, +) { + protected abstract val integrationsClassDescriptor: String + + protected val resolveSLinkMethod = + "patchResolveSLink(Ljava/lang/String;)Z" + + protected val setAccessTokenMethod = + "patchSetAccessToken(Ljava/lang/String;)V" + + override fun execute(context: BytecodeContext) { + handleNavigationFingerprint.resultOrThrow().patchNavigationHandler(context) + setAccessTokenFingerprint.resultOrThrow().patchSetAccessToken(context) + } + + /** + * Patch app's navigation handler to resolve /s/ links. + * + * @param context The current [BytecodeContext]. + * + */ + protected abstract fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) + + /** + * Patch access token setup in app to resolve /s/ links with an access token + * in order to bypass API bans when making unauthorized requests. + * + * @param context The current [BytecodeContext]. + */ + protected abstract fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch.kt new file mode 100644 index 00000000..b651abde --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch.kt @@ -0,0 +1,44 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint.MethodFingerprintResult +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch +import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.GetOAuthAccessTokenFingerprint +import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.HandleNavigationFingerprint +import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.IntegrationsPatch + +@Suppress("unused") +object FixSLinksPatch : BaseFixSLinksPatch( + handleNavigationFingerprint = HandleNavigationFingerprint, + setAccessTokenFingerprint = GetOAuthAccessTokenFingerprint, + compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit")), + dependencies = setOf(IntegrationsPatch::class), +) { + override val integrationsClassDescriptor = "Lapp/revanced/integrations/boostforreddit/FixSLinksPatch;" + + override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) { + mutableMethod.apply { + val urlRegister = "p1" + val tempRegister = "v1" + addInstructionsWithLabels( + 0, + """ + invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod + move-result $tempRegister + if-eqz $tempRegister, :continue + return $tempRegister + """, + ExternalLabel("continue", getInstruction(0)), + ) + } + } + + override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction( + 3, + "invoke-static { v0 }, $integrationsClassDescriptor->$setAccessTokenMethod", + ) +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/GetOAuthAccessTokenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/GetOAuthAccessTokenFingerprint.kt new file mode 100644 index 00000000..9a9103f6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/GetOAuthAccessTokenFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object GetOAuthAccessTokenFingerprint : MethodFingerprint( + strings = listOf("access_token"), + accessFlags = AccessFlags.PUBLIC.value, + returnType = "Ljava/lang/String", + customFingerprint = { _, classDef -> classDef.type == "Lnet/dean/jraw/http/oauth/OAuthData;" }, +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/HandleNavigationFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/HandleNavigationFingerprint.kt new file mode 100644 index 00000000..2a7120a6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/fingerprints/HandleNavigationFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object HandleNavigationFingerprint : MethodFingerprint( + strings = listOf( + "android.intent.action.SEARCH", + "subscription", + "sort", + "period", + "boostforreddit.com/themes", + ), +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch.kt new file mode 100644 index 00000000..c0909a7a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations + +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch +import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints.InitFingerprint + +@Patch(requiresIntegrations = true) +object IntegrationsPatch : BaseIntegrationsPatch( + setOf(InitFingerprint) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/fingerprints/InitFingerprint.kt new file mode 100644 index 00000000..ae28bc63 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/fingerprints/InitFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object InitFingerprint : IntegrationsFingerprint( + customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/rubenmayayo/reddit/MyApplication;" && methodDef.name == "onCreate" }, + insertIndexResolver = { 1 } // Insert after call to super class. +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch.kt index 09fa4e37..26c87582 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch.kt @@ -1,32 +1,49 @@ package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint.MethodFingerprintResult +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.LinkHelperOpenLinkFingerprint -import app.revanced.util.exception +import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.SetAuthorizationHeaderFingerprint +import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.IntegrationsPatch -@Patch( - name = "Fix /s/ links", - description = "Fixes the issue where /s/ links do not work.", - compatiblePackages = [ +@Suppress("unused") +object FixSLinksPatch : BaseFixSLinksPatch( + handleNavigationFingerprint = LinkHelperOpenLinkFingerprint, + setAccessTokenFingerprint = SetAuthorizationHeaderFingerprint, + compatiblePackages = setOf( CompatiblePackage("com.laurencedawson.reddit_sync"), CompatiblePackage("com.laurencedawson.reddit_sync.pro"), - CompatiblePackage("com.laurencedawson.reddit_sync.dev") - ], - requiresIntegrations = true -) -object FixSLinksPatch : BytecodePatch( - setOf(LinkHelperOpenLinkFingerprint) + CompatiblePackage("com.laurencedawson.reddit_sync.dev"), + ), + dependencies = setOf(IntegrationsPatch::class), ) { - override fun execute(context: BytecodeContext) = - LinkHelperOpenLinkFingerprint.result?.mutableMethod?.addInstructions( - 1, - """ - invoke-static { p3 }, Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;->resolveSLink(Ljava/lang/String;)Ljava/lang/String; - move-result-object p3 - """ - ) ?: throw LinkHelperOpenLinkFingerprint.exception + override val integrationsClassDescriptor = "Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;" + + override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) { + mutableMethod.apply { + val urlRegister = "p3" + val tempRegister = "v2" + + addInstructionsWithLabels( + 0, + """ + invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod + move-result $tempRegister + if-eqz $tempRegister, :continue + return $tempRegister + """, + ExternalLabel("continue", getInstruction(0)), + ) + } + } + + override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction( + 0, + "invoke-static { p0 }, $integrationsClassDescriptor->$setAccessTokenMethod", + ) } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/fingerprints/SetAuthorizationHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/fingerprints/SetAuthorizationHeaderFingerprint.kt new file mode 100644 index 00000000..217ee859 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/fingerprints/SetAuthorizationHeaderFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object SetAuthorizationHeaderFingerprint : MethodFingerprint( + strings = listOf("Authorization", "bearer "), + returnType = "Ljava/util/HashMap;", + customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/laurencedawson/reddit_sync/singleton/a;" }, +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/IntegrationsPatch.kt new file mode 100644 index 00000000..bf5ebc32 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/IntegrationsPatch.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations + +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch +import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.fingerprints.InitFingerprint + +@Patch(requiresIntegrations = true) +object IntegrationsPatch : BaseIntegrationsPatch( + setOf(InitFingerprint) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/fingerprints/InitFingerprint.kt new file mode 100644 index 00000000..950f2cbe --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/misc.integrations/fingerprints/InitFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.fingerprints + +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint + +internal object InitFingerprint : IntegrationsFingerprint( + customFingerprint = { methodDef, classDef -> + methodDef.name == "onCreate" && classDef.type == "Lcom/laurencedawson/reddit_sync/RedditApplication;" + }, + insertIndexResolver = { 1 }, // Insert after call to super class. +) From 561a202bfffc5fcdbab1793f39548d2dae7c8b6b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 8 Jun 2024 16:33:11 +0000 Subject: [PATCH 09/23] chore(release): 4.10.0-dev.3 [skip ci] # [4.10.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.2...v4.10.0-dev.3) (2024-06-08) ### Features * **Boost For Reddit:** Add `Fix /s/ links` patch ([#3154](https://github.com/ReVanced/revanced-patches/issues/3154)) ([5fa9fd2](https://github.com/ReVanced/revanced-patches/commit/5fa9fd2dfef43838d7311a967a3e805256a5d116)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 930d20dd..355e2293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.2...v4.10.0-dev.3) (2024-06-08) + + +### Features + +* **Boost For Reddit:** Add `Fix /s/ links` patch ([#3154](https://github.com/ReVanced/revanced-patches/issues/3154)) ([5fa9fd2](https://github.com/ReVanced/revanced-patches/commit/5fa9fd2dfef43838d7311a967a3e805256a5d116)) + # [4.10.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.1...v4.10.0-dev.2) (2024-06-08) diff --git a/gradle.properties b/gradle.properties index d97c7ab7..72cd71e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.2 +version = 4.10.0-dev.3 From a9258d48d3ddf8552ab56219677a3b31ee553666 Mon Sep 17 00:00:00 2001 From: Yan <15308404+OctoNezd@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:42:45 +0300 Subject: [PATCH 10/23] feat(Boost for Reddit): Add `Fix audio missing in video downloads` patch (#3287) Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 6 +++ .../FixAudioMissingInDownloadsPatch.kt | 38 +++++++++++++++++++ .../fingerprints/DownloadAudioFingerprint.kt | 7 ++++ 3 files changed, 51 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/fingerprints/DownloadAudioFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 5b4d8681..299b38f4 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -582,6 +582,12 @@ public final class app/revanced/patches/reddit/customclients/boostforreddit/api/ public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V } +public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch; } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt new file mode 100644 index 00000000..10356965 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt @@ -0,0 +1,38 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads.fingerprints.DownloadAudioFingerprint +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Fix missing audio in video downloads", + description = "Fixes audio missing in videos downloaded from v.redd.it.", + compatiblePackages = [CompatiblePackage("com.rubenmayayo.reddit")], +) +@Suppress("unused") +object FixAudioMissingInDownloadsPatch : BytecodePatch( + setOf(DownloadAudioFingerprint), +) { + private val endpointReplacements = mapOf( + "/DASH_audio.mp4" to "/DASH_AUDIO_128.mp4", + "/audio" to "/DASH_AUDIO_64.mp4", + ) + override fun execute(context: BytecodeContext) { + DownloadAudioFingerprint.resultOrThrow().let { result -> + result.scanResult.stringsScanResult!!.matches.take(2).forEach { match -> + result.mutableMethod.apply { + val replacement = endpointReplacements[match.string] + val register = getInstruction(match.index).registerA + + replaceInstruction(match.index, "const-string v$register, \"$replacement\"") + } + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/fingerprints/DownloadAudioFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/fingerprints/DownloadAudioFingerprint.kt new file mode 100644 index 00000000..b5261523 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/fingerprints/DownloadAudioFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object DownloadAudioFingerprint : MethodFingerprint( + strings = setOf("/DASH_audio.mp4", "/audio", "v.redd.it", "/"), +) From 89f6158149b74447f32ce6f5a4234e78e0642e2b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 8 Jun 2024 16:44:45 +0000 Subject: [PATCH 11/23] chore(release): 4.10.0-dev.4 [skip ci] # [4.10.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.3...v4.10.0-dev.4) (2024-06-08) ### Features * **Boost for Reddit:** Add `Fix audio missing in video downloads` patch ([#3287](https://github.com/ReVanced/revanced-patches/issues/3287)) ([a9258d4](https://github.com/ReVanced/revanced-patches/commit/a9258d48d3ddf8552ab56219677a3b31ee553666)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 355e2293..a158e056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.3...v4.10.0-dev.4) (2024-06-08) + + +### Features + +* **Boost for Reddit:** Add `Fix audio missing in video downloads` patch ([#3287](https://github.com/ReVanced/revanced-patches/issues/3287)) ([a9258d4](https://github.com/ReVanced/revanced-patches/commit/a9258d48d3ddf8552ab56219677a3b31ee553666)) + # [4.10.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.2...v4.10.0-dev.3) (2024-06-08) diff --git a/gradle.properties b/gradle.properties index 72cd71e5..cd20d2f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.3 +version = 4.10.0-dev.4 From c05264af3944cbfe8d9aa34fb0e0fddb05a1d42f Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:31:14 +0300 Subject: [PATCH 12/23] fix(YouTube - Client spoof): Correctly play more livestreams using Android VR (#3316) --- .../fix/playback/UserAgentClientSpoofPatch.kt | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt index 2c0eaceb..2437dfda 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt @@ -8,11 +8,14 @@ import app.revanced.patches.all.misc.transformation.IMethodCall import app.revanced.patches.all.misc.transformation.Instruction35cInfo import app.revanced.patches.all.misc.transformation.filterMapInstruction35c import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.StringReference object UserAgentClientSpoofPatch : BaseTransformInstructionsPatch() { private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube" @@ -42,20 +45,31 @@ object UserAgentClientSpoofPatch : BaseTransformInstructionsPatch()?.toString() - // This can technically also match non-user agent string builder append methods, - // but no such occurrences are present in the app. + // Only replace string builder usage. if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) { return } + // Do not change the package name in methods that use resources, or for methods that use GmsCore. + // Changing these package names will result in playback limitations, + // particularly Android VR background audio only playback. + val resourceOrGmsStringInstructionIndex = indexOfFirstInstruction { + val reference = getReference() + opcode == Opcode.CONST_STRING && + (reference?.string == "android.resource://" || reference?.string == "gcore_") + } + if (resourceOrGmsStringInstructionIndex >= 0) { + return + } + // Overwrite the result of context.getPackageName() with the original package name. replaceInstruction( instructionIndex + 1, - "const-string v$targetRegister, \"${ORIGINAL_PACKAGE_NAME}\"", + "const-string v$targetRegister, \"$ORIGINAL_PACKAGE_NAME\"", ) } } From a6d575fde7964a2fd5ea2c0a8880da3fdda1888d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 9 Jun 2024 08:33:19 +0000 Subject: [PATCH 13/23] chore(release): 4.10.0-dev.5 [skip ci] # [4.10.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.4...v4.10.0-dev.5) (2024-06-09) ### Bug Fixes * **YouTube - Client spoof:** Correctly play more livestreams using Android VR ([#3316](https://github.com/ReVanced/revanced-patches/issues/3316)) ([c05264a](https://github.com/ReVanced/revanced-patches/commit/c05264af3944cbfe8d9aa34fb0e0fddb05a1d42f)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a158e056..5117a06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.4...v4.10.0-dev.5) (2024-06-09) + + +### Bug Fixes + +* **YouTube - Client spoof:** Correctly play more livestreams using Android VR ([#3316](https://github.com/ReVanced/revanced-patches/issues/3316)) ([c05264a](https://github.com/ReVanced/revanced-patches/commit/c05264af3944cbfe8d9aa34fb0e0fddb05a1d42f)) + # [4.10.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.3...v4.10.0-dev.4) (2024-06-08) diff --git a/gradle.properties b/gradle.properties index cd20d2f0..f14ff4b6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.4 +version = 4.10.0-dev.5 From 9c4c4f05a762d745404101bbc3925ab4eba2deb8 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Sun, 9 Jun 2024 14:45:08 +0530 Subject: [PATCH 14/23] feat(YouTube - Comments): Add `Hide Thanks button` and `Hide 'Comments by members' header` options (#3317) --- .../layout/hide/comments/CommentsPatch.kt | 6 +++-- .../resources/addresources/values/strings.xml | 22 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt index 30a77742..20c93ce7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt @@ -62,9 +62,11 @@ object CommentsPatch : ResourcePatch() { PreferenceScreen( "revanced_comments_screen", preferences = setOf( - SwitchPreference("revanced_hide_preview_comment"), + SwitchPreference("revanced_hide_comments_by_members_header"), SwitchPreference("revanced_hide_comments_section"), - SwitchPreference("revanced_hide_comment_timestamp_and_emoji_buttons") + SwitchPreference("revanced_hide_comments_preview_comment"), + SwitchPreference("revanced_hide_comments_thanks_button"), + SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons") ), sorting = PreferenceScreen.Sorting.UNSORTED ) diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 1a85eafc..8ab54f38 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -502,15 +502,21 @@ Comments Hide or show comments section components - Hide preview comment - Preview comment is hidden - Preview comment is shown + Hide \'Comments by members\' header + \'Comments by members\' header is hidden + \'Comments by members\' header is shown Hide comments section - Comment section is hidden - Comment section is shown - Hide timestamp and emoji buttons - Comment timestamp and emoji buttons are hidden - Comment timestamp and emoji buttons are shown + Comments section is hidden + Comments section is shown + Hide preview comment + Preview comment is hidden + Preview comment is shown + Hide thanks button + Thanks button is hidden + Thanks button is shown + Hide timestamp and emoji buttons + Timestamp and emoji buttons are hidden + Timestamp and emoji buttons are shown Hide crowdfunding box From d8e44fcba273f9ec2fed177b8d0aff180b26a221 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 9 Jun 2024 09:17:27 +0000 Subject: [PATCH 15/23] chore(release): 4.10.0-dev.6 [skip ci] # [4.10.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.5...v4.10.0-dev.6) (2024-06-09) ### Features * **YouTube - Comments:** Add `Hide Thanks button` and `Hide 'Comments by members' header` options ([#3317](https://github.com/ReVanced/revanced-patches/issues/3317)) ([9c4c4f0](https://github.com/ReVanced/revanced-patches/commit/9c4c4f05a762d745404101bbc3925ab4eba2deb8)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5117a06f..f8e01ef5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.5...v4.10.0-dev.6) (2024-06-09) + + +### Features + +* **YouTube - Comments:** Add `Hide Thanks button` and `Hide 'Comments by members' header` options ([#3317](https://github.com/ReVanced/revanced-patches/issues/3317)) ([9c4c4f0](https://github.com/ReVanced/revanced-patches/commit/9c4c4f05a762d745404101bbc3925ab4eba2deb8)) + # [4.10.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.4...v4.10.0-dev.5) (2024-06-09) diff --git a/gradle.properties b/gradle.properties index f14ff4b6..a74508f3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.5 +version = 4.10.0-dev.6 From 685ef39119daf1033a83262982519531c481c40f Mon Sep 17 00:00:00 2001 From: 1fexd <58902674+1fexd@users.noreply.github.com> Date: Sat, 15 Jun 2024 18:56:01 +0200 Subject: [PATCH 16/23] feat: Add `Change version code` patch (#3338) Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 6 +++ .../versioncode/ChangeVersionCodePatch.kt | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 299b38f4..2eb9a62f 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -105,6 +105,12 @@ public final class app/revanced/patches/all/misc/transformation/IMethodCall$Defa public static fun replaceInvokeVirtualWithIntegrations (Lapp/revanced/patches/all/misc/transformation/IMethodCall;Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lcom/android/tools/smali/dexlib2/iface/instruction/formats/Instruction35c;I)V } +public final class app/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch : app/revanced/patcher/patch/ResourcePatch { + public static final field INSTANCE Lapp/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch; + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V +} + public final class app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch { public static final field INSTANCE Lapp/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionPatch; public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object; diff --git a/src/main/kotlin/app/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch.kt new file mode 100644 index 00000000..5170332d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/misc/versioncode/ChangeVersionCodePatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.all.misc.versioncode + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.intPatchOption +import app.revanced.util.getNode +import org.w3c.dom.Element + +@Patch( + name = "Change version code", + description = "Changes the version code of the app. By default the highest version code is set. " + + "This allows older versions of an app to be installed " + + "if their version code is set to the same or a higher value and can stop app stores to update the app.", + use = false, +) +@Suppress("unused") +object ChangeVersionCodePatch : ResourcePatch() { + private val versionCode by intPatchOption( + key = "versionCode", + default = Int.MAX_VALUE, + values = mapOf( + "Lowest" to 1, + "Highest" to Int.MAX_VALUE, + ), + title = "Version code", + description = "The version code to use", + required = true, + ) { + it!! >= 1 + } + + override fun execute(context: ResourceContext) { + context.document["AndroidManifest.xml"].use { document -> + val manifestElement = document.getNode("manifest") as Element + manifestElement.setAttribute("android:versionCode", "$versionCode") + } + } +} From 54ad0928b14389d15e5946d9b821160779cc43ab Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 15 Jun 2024 16:58:02 +0000 Subject: [PATCH 17/23] chore(release): 4.10.0-dev.7 [skip ci] # [4.10.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.6...v4.10.0-dev.7) (2024-06-15) ### Features * Add `Change version code` patch ([#3338](https://github.com/ReVanced/revanced-patches/issues/3338)) ([685ef39](https://github.com/ReVanced/revanced-patches/commit/685ef39119daf1033a83262982519531c481c40f)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8e01ef5..f0c21f10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.6...v4.10.0-dev.7) (2024-06-15) + + +### Features + +* Add `Change version code` patch ([#3338](https://github.com/ReVanced/revanced-patches/issues/3338)) ([685ef39](https://github.com/ReVanced/revanced-patches/commit/685ef39119daf1033a83262982519531c481c40f)) + # [4.10.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.5...v4.10.0-dev.6) (2024-06-09) diff --git a/gradle.properties b/gradle.properties index a74508f3..3e506acb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.6 +version = 4.10.0-dev.7 From be9e24420fda80903e44e2e2278ea4904ecac4e1 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Tue, 18 Jun 2024 04:19:08 +0530 Subject: [PATCH 18/23] feat(YouTube - Comments): Add `Hide 'Create a Short' button` option (#3333) Co-authored-by: ILoveOpenSourceApplications --- .../patches/youtube/layout/hide/comments/CommentsPatch.kt | 1 + src/main/resources/addresources/values/strings.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt index 20c93ce7..51280ac1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt @@ -64,6 +64,7 @@ object CommentsPatch : ResourcePatch() { preferences = setOf( SwitchPreference("revanced_hide_comments_by_members_header"), SwitchPreference("revanced_hide_comments_section"), + SwitchPreference("revanced_hide_comments_create_a_short_button"), SwitchPreference("revanced_hide_comments_preview_comment"), SwitchPreference("revanced_hide_comments_thanks_button"), SwitchPreference("revanced_hide_comments_timestamp_and_emoji_buttons") diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 8ab54f38..1bbd46d9 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -508,6 +508,9 @@ Hide comments section Comments section is hidden Comments section is shown + Hide \'Create a Short\' button + \'Create a Short\' button is hidden + \'Create a Short\' button is shown Hide preview comment Preview comment is hidden Preview comment is shown From 8890b1894c0b2af721da6c425fec3f88d62b3748 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 17 Jun 2024 22:51:07 +0000 Subject: [PATCH 19/23] chore(release): 4.10.0-dev.8 [skip ci] # [4.10.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.7...v4.10.0-dev.8) (2024-06-17) ### Features * **YouTube - Comments:** Add `Hide 'Create a Short' button` option ([#3333](https://github.com/ReVanced/revanced-patches/issues/3333)) ([be9e244](https://github.com/ReVanced/revanced-patches/commit/be9e24420fda80903e44e2e2278ea4904ecac4e1)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c21f10..3e9cb9aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.7...v4.10.0-dev.8) (2024-06-17) + + +### Features + +* **YouTube - Comments:** Add `Hide 'Create a Short' button` option ([#3333](https://github.com/ReVanced/revanced-patches/issues/3333)) ([be9e244](https://github.com/ReVanced/revanced-patches/commit/be9e24420fda80903e44e2e2278ea4904ecac4e1)) + # [4.10.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.6...v4.10.0-dev.7) (2024-06-15) diff --git a/gradle.properties b/gradle.properties index 3e506acb..86c9d035 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.7 +version = 4.10.0-dev.8 From 0198a436f97b127a2a5dd283644254f9a0ae3e43 Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Tue, 18 Jun 2024 04:23:56 +0530 Subject: [PATCH 20/23] fix(YouTube - Hide description components): Replace `Hide game section` and `Hide music section` with `Hide attributes section` (#3327) Co-authored-by: ILoveOpenSourceApplications --- .../hide/general/HideLayoutComponentsPatch.kt | 5 ++-- .../resources/addresources/values/strings.xml | 23 ++++++++----------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index b1d8dbf2..acd4d105 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -94,10 +94,9 @@ object HideLayoutComponentsPatch : BytecodePatch( PreferenceScreen( key = "revanced_hide_description_components_screen", preferences = setOf( - SwitchPreference("revanced_hide_chapters"), + SwitchPreference("revanced_hide_attributes_section"), + SwitchPreference("revanced_hide_chapters_section"), SwitchPreference("revanced_hide_info_cards_section"), - SwitchPreference("revanced_hide_game_section"), - SwitchPreference("revanced_hide_music_section"), SwitchPreference("revanced_hide_podcast_section"), SwitchPreference("revanced_hide_transcript_section"), ), diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 1bbd46d9..57dba5ac 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -198,22 +198,19 @@ Hide chips shelf Chips shelf is hidden Chips shelf is shown + Hide attributes section + \'Featured places\', Games and Music sections are hidden + \'Featured places\', Games and Music sections are shown + Hide Chapters section + Chapters section is hidden + Chapters section is shown + Hide \'Explore the podcast\' section + \'Explore the podcast\' section is hidden + \'Explore the podcast\' section is shown Hide info cards section Info cards section is hidden Info cards section is shown - Hide chapters - Chapters are hidden - Chapters are shown - Hide game section - Game section is hidden - Game section is shown - Hide music section - Music section is hidden - Music section is shown - Hide podcast section - Podcast section is hidden - Podcast section is shown - Hide transcript section + Hide Transcript section Transcript section is hidden Transcript section is shown Video description From a85cdbabf888412e891fa00be1d44679685af95d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 17 Jun 2024 22:55:53 +0000 Subject: [PATCH 21/23] chore(release): 4.10.0-dev.9 [skip ci] # [4.10.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.8...v4.10.0-dev.9) (2024-06-17) ### Bug Fixes * **YouTube - Hide description components:** Replace `Hide game section` and `Hide music section` with `Hide attributes section` ([#3327](https://github.com/ReVanced/revanced-patches/issues/3327)) ([0198a43](https://github.com/ReVanced/revanced-patches/commit/0198a436f97b127a2a5dd283644254f9a0ae3e43)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e9cb9aa..be7f4a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.8...v4.10.0-dev.9) (2024-06-17) + + +### Bug Fixes + +* **YouTube - Hide description components:** Replace `Hide game section` and `Hide music section` with `Hide attributes section` ([#3327](https://github.com/ReVanced/revanced-patches/issues/3327)) ([0198a43](https://github.com/ReVanced/revanced-patches/commit/0198a436f97b127a2a5dd283644254f9a0ae3e43)) + # [4.10.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.7...v4.10.0-dev.8) (2024-06-17) diff --git a/gradle.properties b/gradle.properties index 86c9d035..5024680c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.8 +version = 4.10.0-dev.9 From b84494f4e26e040ada69ed7a516f331f2d47da87 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 18 Jun 2024 02:45:42 +0200 Subject: [PATCH 22/23] fix: Correct invalid string name --- src/main/resources/addresources/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 57dba5ac..2eb59f17 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -201,9 +201,9 @@ Hide attributes section \'Featured places\', Games and Music sections are hidden \'Featured places\', Games and Music sections are shown - Hide Chapters section - Chapters section is hidden - Chapters section is shown + Hide Chapters section + Chapters section is hidden + Chapters section is shown Hide \'Explore the podcast\' section \'Explore the podcast\' section is hidden \'Explore the podcast\' section is shown From b8166b998ecbdb7983e2d128f70c498446cc5abd Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 18 Jun 2024 00:47:34 +0000 Subject: [PATCH 23/23] chore(release): 4.10.0-dev.10 [skip ci] # [4.10.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.9...v4.10.0-dev.10) (2024-06-18) ### Bug Fixes * Correct invalid string name ([b84494f](https://github.com/ReVanced/revanced-patches/commit/b84494f4e26e040ada69ed7a516f331f2d47da87)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be7f4a13..47933c9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [4.10.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.9...v4.10.0-dev.10) (2024-06-18) + + +### Bug Fixes + +* Correct invalid string name ([b84494f](https://github.com/ReVanced/revanced-patches/commit/b84494f4e26e040ada69ed7a516f331f2d47da87)) + # [4.10.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.10.0-dev.8...v4.10.0-dev.9) (2024-06-17) diff --git a/gradle.properties b/gradle.properties index 5024680c..cb77af6d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.10.0-dev.9 +version = 4.10.0-dev.10