refactor: more wip

This commit is contained in:
drobotk 2026-03-06 11:24:39 +01:00
parent 1f8a6f2040
commit 2ca6f943e4
No known key found for this signature in database
GPG key ID: D53DB3B14C514056
24 changed files with 290 additions and 590 deletions

View file

@ -23,7 +23,6 @@ import app.revanced.patches.youtube.misc.engagement.addEngagementPanelIdHook
import app.revanced.patches.youtube.misc.engagement.engagementPanelHookPatch
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fixBackToExitGesturePatch
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -153,20 +152,17 @@ val hideAdsPatch = bytecodePatch(
// Hide player overlay view. This can be hidden with a regular litho filter
// but an empty space remains.
if (is_20_14_or_greater) {
playerOverlayTimelyShelfMethod.addInstructionsWithLabels(
0,
"""
invoke-static {}, ${EXTENSION_CLASS_DESCRIPTOR}->hideAds()Z
move-result v0
if-eqz v0, :show
return-void
:show
nop
"""
)
}
playerOverlayTimelyShelfMethod.addInstructionsWithLabels(
0,
"""
invoke-static {}, ${EXTENSION_CLASS_DESCRIPTOR}->hideAds()Z
move-result v0
if-eqz v0, :show
return-void
:show
nop
"""
)
// Hide end screen store banner.

View file

@ -7,13 +7,11 @@ import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import java.util.logging.Logger
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableDoubleTapActionsPatch;"
@ -42,15 +40,6 @@ val disableDoubleTapActionsPatch = bytecodePatch(
)
apply {
if (!is_20_14_or_greater) {
// Show a message if users have version constrain off and are patching the oldest version,
// just to prevent spamming a cryptic error message the user may not understand
// and don't add in app settings that won't work.
return@apply Logger.getLogger(this::class.java.name).warning(
"Disable double tap actions requires 20.14.43+",
)
}
addResources("youtube", "interaction.doubletap.disableDoubleTapActionsPatch")
PreferenceScreen.PLAYER.addPreferences(

View file

@ -9,7 +9,6 @@ import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -73,35 +72,18 @@ val enableSlideToSeekPatch = bytecodePatch(
if (!modifiedMethods) throw PatchException("Could not find methods to modify")
// Disable the double speed seek gesture.
if (is_19_17_or_greater) {
disableFastForwardGestureMethodMatch.let {
it.method.apply {
val targetIndex = it[-1]
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
disableFastForwardGestureMethodMatch.let {
it.method.apply {
val targetIndex = it[-1]
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1,
"""
invoke-static { v$targetRegister }, $extensionMethodDescriptor
move-result v$targetRegister
""",
)
}
}
} else {
disableFastForwardLegacyMethodMatch.let {
it.method.apply {
val insertIndex = it[-1] + 1
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex,
"""
invoke-static { v$targetRegister }, $extensionMethodDescriptor
move-result v$targetRegister
""",
)
}
addInstructions(
targetIndex + 1,
"""
invoke-static { v$targetRegister }, $extensionMethodDescriptor
move-result v$targetRegister
""",
)
}
}
}

View file

@ -12,7 +12,6 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_22_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_34_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
@ -39,7 +38,7 @@ private val swipeControlsResourcePatch = resourcePatch {
// If fullscreen swipe is enabled in newer versions the app can crash.
// It likely is caused by conflicting experimental flags that are never enabled together.
// Flag was completely removed in 20.34+
if (is_19_43_or_greater && !is_20_22_or_greater) {
if (!is_20_22_or_greater) {
PreferenceScreen.SWIPE_CONTROLS.addPreferences(
SwitchPreference("revanced_swipe_change_video"),
)
@ -140,7 +139,7 @@ val swipeControlsPatch = bytecodePatch(
// region patch to enable/disable swipe to change video.
if (is_19_43_or_greater && !is_20_34_or_greater) {
if (!is_20_34_or_greater) {
swipeChangeVideoMethodMatch.let {
it.method.insertLiteralOverride(
it[-1],

View file

@ -18,7 +18,6 @@ import app.revanced.patches.youtube.misc.contexthook.hookClientContextPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.navigation.hookNavigationButtonCreated
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_15_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_31_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
@ -78,17 +77,15 @@ val navigationBarPatch = bytecodePatch(
SwitchPreference("revanced_narrow_navigation_buttons"),
)
if (is_19_25_or_greater) {
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_light")
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_dark")
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_light")
preferences += SwitchPreference("revanced_disable_translucent_navigation_bar_dark")
PreferenceScreen.GENERAL.addPreferences(
SwitchPreference("revanced_disable_translucent_status_bar")
)
PreferenceScreen.GENERAL.addPreferences(
SwitchPreference("revanced_disable_translucent_status_bar")
)
if (is_20_15_or_greater) {
preferences += SwitchPreference("revanced_navigation_bar_animations")
}
if (is_20_15_or_greater) {
preferences += SwitchPreference("revanced_navigation_bar_animations")
}
PreferenceScreen.GENERAL.addPreferences(
@ -124,27 +121,25 @@ val navigationBarPatch = bytecodePatch(
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
// Force on/off translucent effect on status bar and navigation buttons.
if (is_19_25_or_greater) {
translucentNavigationStatusBarFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
)
}
translucentNavigationStatusBarFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
)
}
translucentNavigationButtonsFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
translucentNavigationButtonsFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
translucentNavigationButtonsSystemFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
translucentNavigationButtonsSystemFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
if (is_20_15_or_greater) {

View file

@ -3,7 +3,6 @@ package app.revanced.patches.youtube.layout.hide.endscreencards
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources
@ -12,7 +11,6 @@ import app.revanced.patches.shared.misc.mapping.ResourceType
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -90,18 +88,16 @@ val hideEndScreenCardsPatch = bytecodePatch(
}
}
if (is_19_43_or_greater) {
showEndscreenCardsMethod.addInstructionsWithLabels(
0,
"""
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->hideEndScreenCards()Z
move-result v0
if-eqz v0, :show
return-void
:show
nop
""",
)
}
showEndscreenCardsMethod.addInstructionsWithLabels(
0,
"""
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->hideEndScreenCards()Z
move-result v0
if-eqz v0, :show
return-void
:show
nop
""",
)
}
}

View file

@ -256,15 +256,12 @@ val hideShortsComponentsPatch = bytecodePatch(
}
// Hook to hide the shared navigation bar when the Shorts player is opened.
(
if (is_20_45_or_greater) {
renderBottomNavigationBarParentMethod
} else if (is_19_41_or_greater) {
renderBottomNavigationBarLegacy1941ParentMethod
} else {
legacyRenderBottomNavigationBarLegacyParentMethod
}
).immutableClassDef.getRenderBottomNavigationBarMethodMatch().addInstruction(
if (is_20_45_or_greater) {
renderBottomNavigationBarParentMethod
} else {
renderBottomNavigationBarLegacy1941ParentMethod
}.immutableClassDef.getRenderBottomNavigationBarMethodMatch().addInstruction(
0,
"invoke-static { p1 }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar(Ljava/lang/String;)V",
)
@ -292,20 +289,19 @@ val hideShortsComponentsPatch = bytecodePatch(
// Flags might be present in earlier targets, but they are not found in 19.47.53.
// If these flags are forced on, the experimental layout is still not used, and
// it appears the features requires additional server side data to fully use.
if (is_20_07_or_greater) {
// Experimental Shorts player uses Android native buttons and not Litho,
// and the layout is provided by the server.
//
// Since the buttons are native components and not Litho, it should be possible to
// fix the RYD Shorts loading delay by asynchronously loading RYD and updating
// the button text after RYD has loaded.
shortsExperimentalPlayerFeatureFlagMethod.returnLate(false)
// Experimental UI renderer must also be disabled since it requires the
// experimental Shorts player. If this is enabled but Shorts player
// is disabled then the app crashes when the Shorts player is opened.
renderNextUIFeatureFlagMethod.returnLate(false)
}
// Experimental Shorts player uses Android native buttons and not Litho,
// and the layout is provided by the server.
//
// Since the buttons are native components and not Litho, it should be possible to
// fix the RYD Shorts loading delay by asynchronously loading RYD and updating
// the button text after RYD has loaded.
shortsExperimentalPlayerFeatureFlagMethod.returnLate(false)
// Experimental UI renderer must also be disabled since it requires the
// experimental Shorts player. If this is enabled but Shorts player
// is disabled then the app crashes when the Shorts player is opened.
renderNextUIFeatureFlagMethod.returnLate(false)
// endregion
}

View file

@ -1,12 +1,10 @@
package app.revanced.patches.youtube.layout.player.fullscreen
import app.revanced.patcher.CompositeMatch
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlayerPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.insertLiteralOverride
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -25,26 +23,18 @@ internal val openVideosFullscreenHookPatch = bytecodePatch {
)
apply {
var match: CompositeMatch
var insertIndex: Int
val match = openVideosFullscreenPortraitMethodMatch
val insertIndex = match[0]
if (is_19_46_or_greater) {
match = openVideosFullscreenPortraitMethodMatch
insertIndex = match[0]
openVideosFullscreenPortraitMethodMatch.let {
// Remove A/B feature call that forces what this patch already does.
// Cannot use the A/B flag to accomplish the same goal because 19.50+
// Shorts fullscreen regular player does not use fullscreen
// if the player is minimized, and it must be forced using other conditional check.
it.method.insertLiteralOverride(
it[-1],
false,
)
}
} else {
match = openVideosFullscreenPortraitLegacyMethodMatch
insertIndex = match[-1]
match.let {
// Remove A/B feature call that forces what this patch already does.
// Cannot use the A/B flag to accomplish the same goal because 19.50+
// Shorts fullscreen regular player does not use fullscreen
// if the player is minimized, and it must be forced using other conditional check.
it.method.insertLiteralOverride(
it[-1],
false,
)
}
match.method.apply {

View file

@ -43,7 +43,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/litho/ReturnYouTubeDislikeFilter;"
@Suppress("ObjectPropertyName")
@Suppress("unused")
val returnYouTubeDislikePatch = bytecodePatch(
name = "Return YouTube Dislike",
description = "Adds an option to show the dislike count of videos with Return YouTube Dislike.",
@ -146,36 +146,18 @@ val returnYouTubeDislikePatch = bytecodePatch(
// Find the instruction for creating the text data object.
val textDataClassType = textComponentDataMethod.immutableClassDef.type
val insertIndex: Int
val charSequenceRegister: Int
if (is_19_33_or_greater && !is_20_10_or_greater) {
val index = indexOfFirstInstructionOrThrow {
(opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) &&
methodReference?.returnType == textDataClassType
}
insertIndex = indexOfFirstInstructionOrThrow(index) {
opcode == Opcode.INVOKE_VIRTUAL &&
methodReference?.parameterTypes?.firstOrNull() == "Ljava/lang/CharSequence;"
}
charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
} else {
insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.NEW_INSTANCE &&
typeReference?.type == textDataClassType
}
val charSequenceIndex = indexOfFirstInstructionOrThrow(insertIndex) {
opcode == Opcode.IPUT_OBJECT &&
fieldReference?.type == "Ljava/lang/CharSequence;"
}
charSequenceRegister =
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
val insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.NEW_INSTANCE &&
typeReference?.type == textDataClassType
}
val charSequenceIndex = indexOfFirstInstructionOrThrow(insertIndex) {
opcode == Opcode.IPUT_OBJECT &&
fieldReference?.type == "Ljava/lang/CharSequence;"
}
val charSequenceRegister =
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
val conversionContext = findFreeRegister(insertIndex, charSequenceRegister)
addInstructionsAtControlFlowLabel(
@ -194,38 +176,36 @@ val returnYouTubeDislikePatch = bytecodePatch(
}
// Hook new litho text creation code.
if (is_20_07_or_greater) {
textComponentFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useNewLithoTextCreation(Z)Z"
textComponentFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useNewLithoTextCreation(Z)Z"
)
}
lithoSpannableStringCreationMethodMatch.let {
val conversionContextField = it.immutableClassDef.type +
"->" + textComponentConversionContextField.name +
":" + textComponentConversionContextField.type
it.method.apply {
val insertIndex = it[1]
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
val conversionContextPathRegister =
findFreeRegister(insertIndex, charSequenceRegister)
addInstructions(
insertIndex,
"""
move-object/from16 v$conversionContextPathRegister, p0
iget-object v$conversionContextPathRegister, v$conversionContextPathRegister, $conversionContextField
iget-object v$conversionContextPathRegister, v$conversionContextPathRegister, $conversionContextPathBuilderField
invoke-static { v$conversionContextPathRegister, v$charSequenceRegister }, $EXTENSION_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
"""
)
}
lithoSpannableStringCreationMethodMatch.let {
val conversionContextField = it.immutableClassDef.type +
"->" + textComponentConversionContextField.name +
":" + textComponentConversionContextField.type
it.method.apply {
val insertIndex = it[1]
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
val conversionContextPathRegister =
findFreeRegister(insertIndex, charSequenceRegister)
addInstructions(
insertIndex,
"""
move-object/from16 v$conversionContextPathRegister, p0
iget-object v$conversionContextPathRegister, v$conversionContextPathRegister, $conversionContextField
iget-object v$conversionContextPathRegister, v$conversionContextPathRegister, $conversionContextPathBuilderField
invoke-static { v$conversionContextPathRegister, v$charSequenceRegister }, $EXTENSION_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
"""
)
}
}
}
// endregion

View file

@ -11,8 +11,6 @@ import app.revanced.patches.shared.layout.theme.lithoColorHookPatch
import app.revanced.patches.shared.layout.theme.lithoColorOverrideHook
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_21_02_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
@ -90,20 +88,18 @@ val seekbarColorPatch = bytecodePatch(
// If hiding feed seekbar thumbnails, then turn off the cairo gradient
// of the watch history menu items as they use the same gradient as the
// player and there is no easy way to distinguish which to use a transparent color.
if (is_19_34_or_greater) {
watchHistoryMenuUseProgressDrawableMethodMatch.let {
it.method.apply {
val index = it[1]
val register = getInstruction<OneRegisterInstruction>(index).registerA
watchHistoryMenuUseProgressDrawableMethodMatch.let {
it.method.apply {
val index = it[1]
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index + 1,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->showWatchHistoryProgressDrawable(Z)Z
move-result v$register
""",
)
}
addInstructions(
index + 1,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->showWatchHistoryProgressDrawable(Z)Z
move-result v$register
""",
)
}
}
@ -115,44 +111,23 @@ val seekbarColorPatch = bytecodePatch(
""",
)
val playerMatch: CompositeMatch
val checkGradientCoordinates: Boolean
if (is_19_49_or_greater) {
playerMatch = playerLinearGradientMethodMatch
checkGradientCoordinates = true
} else {
playerMatch = playerLinearGradientLegacyMethodMatch
checkGradientCoordinates = false
}
playerMatch.let {
playerLinearGradientMethodMatch.let {
it.method.apply {
val index = it[-1]
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index + 1,
if (checkGradientCoordinates) {
"""
invoke-static { v$register, p0, p1 }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([III)[I
move-result-object v$register
"""
} else {
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([I)[I
move-result-object v$register
"""
},
"""
invoke-static { v$register, p0, p1 }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([III)[I
move-result-object v$register
"""
)
}
}
// region apply seekbar custom color to splash screen animation.
if (!is_19_34_or_greater) {
return@apply // 19.25 does not have a cairo launch animation.
}
// Hook the splash animation to set the seekbar color.
mainActivityOnCreateMethod.apply {
val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntMethod.name

View file

@ -13,8 +13,6 @@ import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_09_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -35,7 +33,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/ShortsAutoplayPatch;"
@Suppress("ObjectPropertyName")
@Suppress("unused")
val shortsAutoplayPatch = bytecodePatch(
name = "Shorts autoplay",
description = "Adds options to automatically play the next Short.",
@ -65,11 +63,9 @@ val shortsAutoplayPatch = bytecodePatch(
SwitchPreference("revanced_shorts_autoplay"),
)
if (is_19_34_or_greater) {
PreferenceScreen.SHORTS.addPreferences(
SwitchPreference("revanced_shorts_autoplay_background"),
)
}
PreferenceScreen.SHORTS.addPreferences(
SwitchPreference("revanced_shorts_autoplay_background"),
)
// Main activity is used to check if app is in pip mode.
mainActivityOnCreateMethod.addInstruction(
@ -118,79 +114,78 @@ val shortsAutoplayPatch = bytecodePatch(
// As of YouTube 20.09, Google has removed the code for 'Autoplay' and 'Pause' from this method.
// Manually restore the removed 'Autoplay' code.
if (is_20_09_or_greater) {
// Variable names are only a rough guess of what these methods do.
val userActionMethodReference =
reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[1]).methodReference!!
val reelSequenceControllerMethodReference =
reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[2]).methodReference!!
reelPlaybackRepeatMethod.apply {
// Find the first call modified by extension code above.
val extensionReturnResultIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC &&
getReference<MethodReference>()?.definingClass == EXTENSION_CLASS_DESCRIPTOR
} + 1
val enumRegister =
getInstruction<OneRegisterInstruction>(extensionReturnResultIndex).registerA
val getReelSequenceControllerIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<FieldReference>()
opcode == Opcode.IGET_OBJECT &&
reference?.definingClass == definingClass &&
reference.type == reelSequenceControllerMethodReference.definingClass
}
val getReelSequenceControllerReference =
getInstruction<ReferenceInstruction>(getReelSequenceControllerIndex).reference
// Variable names are only a rough guess of what these methods do.
val userActionMethodReference =
reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[1]).methodReference!!
val reelSequenceControllerMethodReference =
reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[2]).methodReference!!
// Add a helper method to avoid finding multiple free registers.
// If enum is autoplay then method performs autoplay and returns null,
// otherwise returns the same enum.
val helperClass = definingClass
val helperName = "patch_handleAutoPlay"
val helperReturnType = "Ljava/lang/Enum;"
val helperMethod = ImmutableMethod(
helperClass,
helperName,
listOf(ImmutableMethodParameter("Ljava/lang/Enum;", null, null)),
helperReturnType,
AccessFlags.PRIVATE.value,
null,
null,
MutableMethodImplementation(7),
).toMutable().apply {
addInstructionsWithLabels(
0,
"""
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->isAutoPlay(Ljava/lang/Enum;)Z
move-result v0
if-eqz v0, :ignore
new-instance v0, ${userActionMethodReference.definingClass}
const/4 v1, 0x3
const/4 v2, 0x0
invoke-direct { v0, v1, v2, v2 }, $userActionMethodReference
iget-object v3, p0, $getReelSequenceControllerReference
invoke-virtual { v3, v0 }, $reelSequenceControllerMethodReference
const/4 v4, 0x0
return-object v4
:ignore
return-object p1
""",
)
}
reelPlaybackRepeatMethod.classDef.methods.add(helperMethod)
reelPlaybackRepeatMethod.apply {
// Find the first call modified by extension code above.
val extensionReturnResultIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC &&
getReference<MethodReference>()?.definingClass == EXTENSION_CLASS_DESCRIPTOR
} + 1
val enumRegister =
getInstruction<OneRegisterInstruction>(extensionReturnResultIndex).registerA
val getReelSequenceControllerIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<FieldReference>()
opcode == Opcode.IGET_OBJECT &&
reference?.definingClass == definingClass &&
reference.type == reelSequenceControllerMethodReference.definingClass
}
val getReelSequenceControllerReference =
getInstruction<ReferenceInstruction>(getReelSequenceControllerIndex).reference
// Add a helper method to avoid finding multiple free registers.
// If enum is autoplay then method performs autoplay and returns null,
// otherwise returns the same enum.
val helperClass = definingClass
val helperName = "patch_handleAutoPlay"
val helperReturnType = "Ljava/lang/Enum;"
val helperMethod = ImmutableMethod(
helperClass,
helperName,
listOf(ImmutableMethodParameter("Ljava/lang/Enum;", null, null)),
helperReturnType,
AccessFlags.PRIVATE.value,
null,
null,
MutableMethodImplementation(7),
).toMutable().apply {
addInstructionsWithLabels(
extensionReturnResultIndex + 1,
0,
"""
invoke-direct { p0, v$enumRegister }, $helperClass->$helperName(Ljava/lang/Enum;)$helperReturnType
move-result-object v$enumRegister
if-nez v$enumRegister, :ignore
return-void # Autoplay was performed.
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->isAutoPlay(Ljava/lang/Enum;)Z
move-result v0
if-eqz v0, :ignore
new-instance v0, ${userActionMethodReference.definingClass}
const/4 v1, 0x3
const/4 v2, 0x0
invoke-direct { v0, v1, v2, v2 }, $userActionMethodReference
iget-object v3, p0, $getReelSequenceControllerReference
invoke-virtual { v3, v0 }, $reelSequenceControllerMethodReference
const/4 v4, 0x0
return-object v4
:ignore
nop
return-object p1
""",
)
}
reelPlaybackRepeatMethod.classDef.methods.add(helperMethod)
addInstructionsWithLabels(
extensionReturnResultIndex + 1,
"""
invoke-direct { p0, v$enumRegister }, $helperClass->$helperName(Ljava/lang/Enum;)$helperReturnType
move-result-object v$enumRegister
if-nez v$enumRegister, :ignore
return-void # Autoplay was performed.
:ignore
nop
""",
)
}
}
}

View file

@ -7,18 +7,11 @@ import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_20_03_or_greater
import app.revanced.patches.youtube.misc.playservice.is_21_03_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.addInstructionsAtControlFlowLabel
import app.revanced.util.findFreeRegister
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch;"
@ -59,40 +52,17 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
SwitchPreference("revanced_disable_resuming_shorts_player"),
)
if (is_20_03_or_greater) {
userWasInShortsAlternativeMethodMatch.let {
it.method.apply {
val insertIndex = it[2] + 1
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
userWasInShortsAlternativeMethodMatch.let {
it.method.apply {
val insertIndex = it[2] + 1
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z
move-result v$register
""",
)
}
}
} else {
userWasInShortsLegacyMethod.apply {
val listenableInstructionIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_INTERFACE &&
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
getReference<MethodReference>()?.name == "isDone"
}
val freeRegister = findFreeRegister(listenableInstructionIndex)
addInstructionsAtControlFlowLabel(
listenableInstructionIndex,
"""
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
move-result v$freeRegister
if-eqz v$freeRegister, :show_startup_shorts_player
return-void
:show_startup_shorts_player
nop
addInstructions(
insertIndex,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z
move-result v$register
""",
)
}
}

View file

@ -1,8 +1,8 @@
package app.revanced.patches.youtube.layout.theme
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption
@ -24,8 +24,6 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater
import app.revanced.patches.youtube.misc.playservice.is_21_06_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
@ -230,24 +228,20 @@ val themePatch = baseThemePatch(
),
)
if (is_19_47_or_greater) {
PreferenceScreen.GENERAL.addPreferences(
ListPreference("revanced_splash_screen_animation_style"),
)
}
PreferenceScreen.GENERAL.addPreferences(
ListPreference("revanced_splash_screen_animation_style"),
)
useGradientLoadingScreenMethodMatch.method.insertLiteralOverride(
useGradientLoadingScreenMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z",
)
if (is_19_47_or_greater) {
// Lottie splash screen exists in earlier versions, but it may not be always on.
splashScreenStyleMethodMatch.method.insertLiteralOverride(
splashScreenStyleMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I",
)
}
// Lottie splash screen exists in earlier versions, but it may not be always on.
splashScreenStyleMethodMatch.method.insertLiteralOverride(
splashScreenStyleMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I",
)
showSplashScreen1MethodMatch.let {
it.method.apply {
@ -264,22 +258,20 @@ val themePatch = baseThemePatch(
}
}
if (is_20_02_or_greater) {
showSplashScreen2MethodMatch.let {
val insertIndex = it[1]
it.method.apply {
val insertInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
val registerA = insertInstruction.registerA
val registerB = insertInstruction.registerB
showSplashScreen2MethodMatch.let {
val insertIndex = it[1]
it.method.apply {
val insertInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
val registerA = insertInstruction.registerA
val registerB = insertInstruction.registerB
addInstructions(
insertIndex,
"""
invoke-static { v$registerA, v$registerB }, ${EXTENSION_CLASS_DESCRIPTOR}->showSplashScreen(II)I
move-result v$registerA
"""
)
}
addInstructions(
insertIndex,
"""
invoke-static { v$registerA, v$registerB }, ${EXTENSION_CLASS_DESCRIPTOR}->showSplashScreen(II)I
move-result v$registerA
"""
)
}
}
},

View file

@ -10,7 +10,6 @@ import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_29_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
@ -103,13 +102,11 @@ val removeBackgroundPlaybackRestrictionsPatch = bytecodePatch(
kidsBackgroundPlaybackPolicyControllerMethod.returnEarly()
// Fix PiP buttons not working after locking/unlocking device screen.
if (is_19_34_or_greater) {
pipInputConsumerFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
false,
)
}
pipInputConsumerFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
it[0],
false,
)
}
if (is_20_29_or_greater) {

View file

@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.findFreeRegister
import app.revanced.util.indexOfFirstInstructionOrThrow
@ -37,10 +36,6 @@ val fixPlaybackSpeedWhilePlayingPatch = bytecodePatch {
)
apply {
if (!is_19_34_or_greater) {
return@apply
}
playbackSpeedInFeedsMethod.apply {
val playbackSpeedIndex = indexOfGetPlaybackSpeedInstruction(this)
val playbackSpeedRegister = getInstruction<TwoRegisterInstruction>(playbackSpeedIndex).registerA

View file

@ -13,17 +13,11 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.*
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.insertLiteralOverride
import app.revanced.util.returnLate
import com.android.tools.smali.dexlib2.Opcode
val lithoFilterPatch = lithoFilterPatch(
componentCreateInsertionIndex = {
if (is_19_17_or_greater) {
indexOfFirstInstructionOrThrow(Opcode.RETURN_OBJECT)
} else {
// 19.16 clobbers p2 so must check at start of the method and not at the return index.
0
}
indexOfFirstInstructionOrThrow(Opcode.RETURN_OBJECT)
},
insertProtobufHook = {
if (is_20_22_or_greater) {
@ -49,15 +43,6 @@ val lithoFilterPatch = lithoFilterPatch(
executeBlock = {
// region A/B test of new Litho native code.
// Turn off native code that handles litho component names. If this feature is on then nearly
// all litho components have a null name and identifier/path filtering is completely broken.
//
// Flag was removed in 20.05. It appears a new flag might be used instead (45660109L),
// but if the flag is forced on then litho filtering still works correctly.
if (is_19_25_or_greater && !is_20_05_or_greater) {
lithoComponentNameUpbFeatureFlagMethod.returnLate(false)
}
// Turn off a feature flag that enables native code of protobuf parsing (Upb protobuf).
lithoConverterBufferUpbFeatureFlagMethodMatch.let {
// 20.22 the flag is still enabled in one location, but what it does is not known.
@ -67,6 +52,7 @@ val lithoFilterPatch = lithoFilterPatch(
false,
)
}
// endregion
}
) {

View file

@ -27,12 +27,9 @@ import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
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.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.util.MethodUtil
import java.util.logging.Logger
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/shared/NavigationBar;"
@ -205,25 +202,23 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
}
// Fix YT bug of notification tab missing the filled icon.
if (is_19_35_or_greater) {
val cairoNotificationEnumReference =
imageEnumConstructorMethodMatch.method.getInstruction(imageEnumConstructorMethodMatch[-1]).reference
val cairoNotificationEnumReference =
imageEnumConstructorMethodMatch.method.getInstruction(imageEnumConstructorMethodMatch[-1]).reference
setEnumMapMethodMatch.apply {
val setEnumIntegerIndex = setEnumMapMethodMatch[-1]
method.apply {
val enumMapRegister = getInstruction<FiveRegisterInstruction>(setEnumIntegerIndex).registerC
val insertIndex = setEnumIntegerIndex + 1
val freeRegister = findFreeRegister(insertIndex, enumMapRegister)
setEnumMapMethodMatch.apply {
val setEnumIntegerIndex = setEnumMapMethodMatch[-1]
method.apply {
val enumMapRegister = getInstruction<FiveRegisterInstruction>(setEnumIntegerIndex).registerC
val insertIndex = setEnumIntegerIndex + 1
val freeRegister = findFreeRegister(insertIndex, enumMapRegister)
addInstructions(
insertIndex,
"""
sget-object v$freeRegister, $cairoNotificationEnumReference
invoke-static { v$enumMapRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->setCairoNotificationFilledIcon(Ljava/util/EnumMap;Ljava/lang/Enum;)V
""",
)
}
addInstructions(
insertIndex,
"""
sget-object v$freeRegister, $cairoNotificationEnumReference
invoke-static { v$enumMapRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->setCairoNotificationFilledIcon(Ljava/util/EnumMap;Ljava/lang/Enum;)V
""",
)
}
}
}

View file

@ -277,16 +277,14 @@ val playerControlsPatch = bytecodePatch(
// that uses layout file youtube_video_exploder_controls_bottom_ui_container.xml
// The change to support this is simple and only requires adding buttons to both layout files,
// but for now force this different layout off since it's still an experimental test.
if (is_19_35_or_greater) {
playerBottomControlsExploderFeatureFlagMethod.returnLate(false)
}
playerBottomControlsExploderFeatureFlagMethod.returnLate(false)
// A/B test of different top overlay controls. Two different layouts can be used:
// youtube_cf_navigation_improvement_controls_layout.xml
// youtube_cf_minimal_impact_controls_layout.xml
//
// Flag was removed in 20.19+
if (is_19_25_or_greater && !is_20_19_or_greater) {
if (!is_20_19_or_greater) {
playerTopControlsExperimentalLayoutFeatureFlagMethod.apply {
val index = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_OBJECT)
val register = getInstruction<OneRegisterInstruction>(index).registerA

View file

@ -8,77 +8,6 @@ import kotlin.properties.Delegates
// Use notNull delegate so an exception is thrown if these fields are accessed before they are set.
@Deprecated("20.14.43 is the lowest supported version")
var is_19_17_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_18_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_23_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_25_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_26_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_29_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_32_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_33_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_34_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_35_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_36_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_41_or_greater: Boolean by Delegates.notNull()
private set
@Deprecated("20.14.43 is the lowest supported version")
var is_19_43_or_greater: Boolean by Delegates.notNull()
private set
var is_19_46_or_greater: Boolean by Delegates.notNull()
private set
var is_19_47_or_greater: Boolean by Delegates.notNull()
private set
var is_19_49_or_greater: Boolean by Delegates.notNull()
private set
var is_20_02_or_greater: Boolean by Delegates.notNull()
private set
var is_20_03_or_greater: Boolean by Delegates.notNull()
private set
var is_20_05_or_greater: Boolean by Delegates.notNull()
private set
var is_20_07_or_greater: Boolean by Delegates.notNull()
private set
var is_20_09_or_greater: Boolean by Delegates.notNull()
private set
var is_20_10_or_greater: Boolean by Delegates.notNull()
private set
var is_20_14_or_greater: Boolean by Delegates.notNull()
private set
var is_20_15_or_greater: Boolean by Delegates.notNull()
private set
var is_20_19_or_greater: Boolean by Delegates.notNull()
@ -137,29 +66,6 @@ val versionCheckPatch = resourcePatch(
val playStoreServicesVersion = findPlayStoreServicesVersion()
// All bug fix releases always seem to use the same play store version as the minor version.
is_19_17_or_greater = 241802000 <= playStoreServicesVersion
is_19_18_or_greater = 241902000 <= playStoreServicesVersion
is_19_23_or_greater = 242402000 <= playStoreServicesVersion
is_19_25_or_greater = 242599000 <= playStoreServicesVersion
is_19_26_or_greater = 242705000 <= playStoreServicesVersion
is_19_29_or_greater = 243005000 <= playStoreServicesVersion
is_19_32_or_greater = 243199000 <= playStoreServicesVersion
is_19_33_or_greater = 243405000 <= playStoreServicesVersion
is_19_34_or_greater = 243499000 <= playStoreServicesVersion
is_19_35_or_greater = 243605000 <= playStoreServicesVersion
is_19_36_or_greater = 243705000 <= playStoreServicesVersion
is_19_41_or_greater = 244305000 <= playStoreServicesVersion
is_19_43_or_greater = 244405000 <= playStoreServicesVersion
is_19_46_or_greater = 244705000 <= playStoreServicesVersion
is_19_47_or_greater = 244799000 <= playStoreServicesVersion
is_19_49_or_greater = 245005000 <= playStoreServicesVersion
is_20_02_or_greater = 250299000 <= playStoreServicesVersion
is_20_03_or_greater = 250405000 <= playStoreServicesVersion
is_20_05_or_greater = 250605000 <= playStoreServicesVersion
is_20_07_or_greater = 250805000 <= playStoreServicesVersion
is_20_09_or_greater = 251006000 <= playStoreServicesVersion
is_20_10_or_greater = 251105000 <= playStoreServicesVersion
is_20_14_or_greater = 251505000 <= playStoreServicesVersion
is_20_15_or_greater = 251605000 <= playStoreServicesVersion
is_20_19_or_greater = 252005000 <= playStoreServicesVersion
is_20_20_or_greater = 252105000 <= playStoreServicesVersion

View file

@ -21,7 +21,6 @@ import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.fix.contentprovider.fixContentProviderPatch
import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_31_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.*
@ -187,11 +186,9 @@ val settingsPatch = bytecodePatch(
selectable = true,
)
if (is_19_34_or_greater) {
PreferenceScreen.GENERAL.addPreferences(
SwitchPreference("revanced_restore_old_settings_menus"),
)
}
PreferenceScreen.GENERAL.addPreferences(
SwitchPreference("revanced_restore_old_settings_menus"),
)
PreferenceScreen.GENERAL.addPreferences(
SwitchPreference("revanced_settings_search_history"),

View file

@ -7,10 +7,6 @@ import app.revanced.patches.shared.misc.settings.preference.NonInteractivePrefer
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_03_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -19,16 +15,9 @@ import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
extensionClassDescriptor = "Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;",
getMainActivityOnCreateMethod = BytecodePatchContext::mainActivityOnCreateMethod::get,
fixMediaFetchHotConfig = {
is_19_34_or_greater
},
fixMediaFetchHotConfigAlternative = {
// In 20.14 the flag was merged with 20.03 start playback flag.
is_20_10_or_greater && !is_20_14_or_greater
},
fixParsePlaybackResponseFeatureFlag = {
is_20_03_or_greater
},
fixMediaFetchHotConfig = { true },
fixMediaFetchHotConfigAlternative = { false },
fixParsePlaybackResponseFeatureFlag = { true },
block = {
compatibleWith(

View file

@ -3,7 +3,6 @@ package app.revanced.patches.youtube.video.audio
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.shared.misc.audio.forceOriginalAudioPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@ -29,7 +28,7 @@ val forceOriginalAudioPatch = forceOriginalAudioPatch(
),
)
},
fixUseLocalizedAudioTrackFlag = { is_20_07_or_greater },
fixUseLocalizedAudioTrackFlag = { true },
getMainActivityOnCreateMethod = BytecodePatchContext::mainActivityOnCreateMethod::get,
subclassExtensionClassDescriptor = "Lapp/revanced/extension/youtube/patches/ForceOriginalAudioPatch;",
preferenceScreen = PreferenceScreen.VIDEO,

View file

@ -5,9 +5,6 @@ import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_15_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_26_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_46_or_greater
@ -50,18 +47,9 @@ val playerResponseMethodHookPatch = bytecodePatch {
} else if (is_20_15_or_greater) {
parameterIsShortAndOpeningOrPlaying = 13
method = playerParameterBuilder2015Method
} else if (is_20_10_or_greater) {
} else {
parameterIsShortAndOpeningOrPlaying = 13
method = playerParameterBuilder2010Method
} else if (is_20_02_or_greater) {
parameterIsShortAndOpeningOrPlaying = 12
method = playerParameterBuilder2002Method
} else if (is_19_23_or_greater) {
parameterIsShortAndOpeningOrPlaying = 12
method = playerParameterBuilder1925Method
} else {
parameterIsShortAndOpeningOrPlaying = 11
method = playerParameterBuilderLegacyMethod
}
playerResponseMethod = method

View file

@ -19,7 +19,6 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.shared.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_34_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.addRecyclerViewTreeHook
@ -65,11 +64,9 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
),
)
if (is_19_47_or_greater) {
settingsMenuVideoSpeedGroup.add(
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
)
}
settingsMenuVideoSpeedGroup.add(
TextPreference("revanced_speed_tap_and_hold", inputType = InputType.NUMBER_DECIMAL),
)
// Override the min/max speeds that can be used.
(if (is_20_34_or_greater) speedLimiterMethod else speedLimiterLegacyMethod).apply {
@ -171,22 +168,20 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
// region Custom tap and hold 2x speed.
if (is_19_47_or_greater) {
// Function, because it can be the same method as getTapAndHoldHapticsMethodMatch.
getTapAndHoldSpeedMethodMatch().let {
it.method.apply {
val speedIndex = it[-1]
val speedRegister =
getInstruction<OneRegisterInstruction>(speedIndex).registerA
// Function, because it can be the same method as getTapAndHoldHapticsMethodMatch.
getTapAndHoldSpeedMethodMatch().let {
it.method.apply {
val speedIndex = it[-1]
val speedRegister =
getInstruction<OneRegisterInstruction>(speedIndex).registerA
addInstructions(
speedIndex + 1,
"""
invoke-static { }, ${EXTENSION_CLASS_DESCRIPTOR}->getTapAndHoldSpeed()F
move-result v$speedRegister
"""
)
}
addInstructions(
speedIndex + 1,
"""
invoke-static { }, ${EXTENSION_CLASS_DESCRIPTOR}->getTapAndHoldSpeed()F
move-result v$speedRegister
"""
)
}
}