feat(YouTube): Support version 19.43.41 (#3854)

This commit is contained in:
LisoUseInAIKyrios 2024-11-03 08:46:20 -04:00 committed by oSumAtrIX
parent 0f42574b7f
commit 85de5c7d96
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
59 changed files with 249 additions and 64 deletions

View File

@ -4,7 +4,22 @@ import app.revanced.extension.youtube.settings.Settings;
/** @noinspection unused*/ /** @noinspection unused*/
public final class DisableFullscreenAmbientModePatch { public final class DisableFullscreenAmbientModePatch {
public static boolean enableFullScreenAmbientMode() {
return !Settings.DISABLE_FULLSCREEN_AMBIENT_MODE.get(); private static final boolean DISABLE_FULLSCREEN_AMBIENT_MODE = Settings.DISABLE_FULLSCREEN_AMBIENT_MODE.get();
/**
* Constant found in: androidx.window.embedding.DividerAttributes
*/
private static final int DIVIDER_ATTRIBUTES_COLOR_SYSTEM_DEFAULT = -16777216;
/**
* Injection point.
*/
public static int getFullScreenBackgroundColor(int originalColor) {
if (DISABLE_FULLSCREEN_AMBIENT_MODE) {
return DIVIDER_ATTRIBUTES_COLOR_SYSTEM_DEFAULT;
}
return originalColor;
} }
} }

View File

@ -0,0 +1,24 @@
package app.revanced.extension.youtube.patches;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
@SuppressWarnings("unused")
public final class EnableDebuggingPatch {
private static final ConcurrentMap<Long, Boolean> featureFlags
= new ConcurrentHashMap<>(150, 0.75f, 1);
public static boolean isFeatureFlagEnabled(long flag, boolean value) {
if (value && BaseSettings.DEBUG.get()) {
if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> "feature is enabled: " + flag);
}
}
return value;
}
}

View File

@ -1053,6 +1053,10 @@ public final class app/revanced/patches/youtube/interaction/seekbar/EnableSlideT
public static final fun getEnableSlideToSeekPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getEnableSlideToSeekPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatchKt {
public static final fun getSeekbarThumbnailsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatchKt { public final class app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatchKt {
public static final fun getSwipeControlsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getSwipeControlsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
@ -1196,10 +1200,6 @@ public final class app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch
public static final fun getSeekbarColorPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getSeekbarColorPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/youtube/layout/seekbar/SeekbarThumbnailsPatchKt {
public static final fun getSeekbarThumbnailsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatchKt { public final class app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatchKt {
public static final fun getShortsAutoplayPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getShortsAutoplayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
@ -1263,7 +1263,7 @@ public final class app/revanced/patches/youtube/misc/check/CheckEnvironmentPatch
} }
public final class app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatchKt { public final class app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatchKt {
public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/ResourcePatch; public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
} }
public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatchKt { public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatchKt {

View File

@ -74,6 +74,7 @@ val hideAdsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -30,6 +30,7 @@ val hideGetPremiumPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -29,6 +29,7 @@ val videoAdsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -58,6 +58,7 @@ val copyVideoUrlPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -30,6 +30,7 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -73,6 +73,7 @@ val downloadsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -30,6 +30,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -32,6 +32,7 @@ val enableSeekbarTappingPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -42,6 +42,7 @@ val enableSlideToSeekPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -1,11 +1,10 @@
package app.revanced.patches.youtube.layout.seekbar package app.revanced.patches.youtube.interaction.seekbar
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.interaction.seekbar.fullscreenSeekbarThumbnailsQualityFingerprint
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch 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.is_19_17_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
@ -32,6 +31,7 @@ val seekbarThumbnailsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
) )
) )

View File

@ -73,6 +73,7 @@ val swipeControlsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -28,6 +28,7 @@ val autoCaptionsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -28,6 +28,7 @@ val hideButtonsPatch = resourcePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -41,6 +41,7 @@ val navigationButtonsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -62,6 +62,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -61,6 +61,7 @@ val hideEndscreenCardsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -1,16 +1,18 @@
package app.revanced.patches.youtube.layout.hide.fullscreenambientmode package app.revanced.patches.youtube.layout.hide.fullscreenambientmode
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch 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.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import java.util.logging.Logger import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal const val EXTENSION_CLASS_DESCRIPTOR = internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;" "Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;"
@ -24,7 +26,6 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
settingsPatch, settingsPatch,
sharedExtensionPatch, sharedExtensionPatch,
addResourcesPatch, addResourcesPatch,
versionCheckPatch,
) )
compatibleWith( compatibleWith(
@ -34,33 +35,31 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )
val initializeAmbientModeMatch by initializeAmbientModeFingerprint() val setFullScreenBackgroundColorMatch by setFullScreenBackgroundColorFingerprint()
execute { execute {
// TODO: fix this patch when 19.43+ is eventually supported.
if (is_19_43_or_greater) {
// 19.43+ the feature flag was inlined as false and no longer exists.
// This patch can be updated to change a single method, but for now show a more descriptive error.
return@execute Logger.getLogger(this::class.java.name)
.severe("'Disable fullscreen ambient mode' does not yet support 19.43+")
}
addResources("youtube", "layout.hide.fullscreenambientmode.disableFullscreenAmbientModePatch") addResources("youtube", "layout.hide.fullscreenambientmode.disableFullscreenAmbientModePatch")
PreferenceScreen.PLAYER.addPreferences( PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_fullscreen_ambient_mode"), SwitchPreference("revanced_disable_fullscreen_ambient_mode"),
) )
initializeAmbientModeMatch.mutableMethod.apply { setFullScreenBackgroundColorMatch.mutableMethod.apply {
val moveIsEnabledIndex = initializeAmbientModeMatch.patternMatch!!.endIndex val insertIndex = indexOfFirstInstructionReversedOrThrow {
getReference<MethodReference>()?.name == "setBackgroundColor"
}
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
addInstruction( addInstructions(
moveIsEnabledIndex, insertIndex,
"invoke-static { }, " + """
"$EXTENSION_CLASS_DESCRIPTOR->enableFullScreenAmbientMode()Z", invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getFullScreenBackgroundColor(I)I
move-result v$register
"""
) )
} }
} }

View File

@ -1,13 +1,14 @@
package app.revanced.patches.youtube.layout.hide.fullscreenambientmode package app.revanced.patches.youtube.layout.hide.fullscreenambientmode
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal val initializeAmbientModeFingerprint = fingerprint { internal val setFullScreenBackgroundColorFingerprint = fingerprint {
returns("V") returns("V")
accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PUBLIC) accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
opcodes(Opcode.MOVE_RESULT) parameters("Z", "I", "I", "I", "I")
literal { 45389368 } custom { method, classDef ->
classDef.type.endsWith("/YouTubePlayerViewNotForReflection;")
&& method.name == "onLayout"
}
} }

View File

@ -128,6 +128,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -63,6 +63,7 @@ val hideInfoCardsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -30,6 +30,7 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -35,6 +35,7 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -32,6 +32,7 @@ val hideSeekbarPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -187,6 +187,7 @@ val hideShortsComponentsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -59,6 +59,7 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -27,6 +27,7 @@ val hideTimestampPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -167,6 +167,7 @@ val miniplayerPatch = bytecodePatch(
// 19.32.36 // 19.32+ and beyond all work without issues. // 19.32.36 // 19.32+ and beyond all work without issues.
// 19.33.35 // 19.33.35
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -27,6 +27,7 @@ val playerPopupPanelsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -17,6 +17,7 @@ val playerControlsBackgroundPatch = resourcePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -60,6 +60,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -35,6 +35,7 @@ val wideSearchbarPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -37,6 +37,7 @@ val shortsAutoplayPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -117,6 +117,7 @@ val sponsorBlockPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -34,6 +34,7 @@ val spoofAppVersionPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -35,6 +35,7 @@ val changeStartPagePatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -37,6 +37,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -32,6 +32,7 @@ val enableTabletLayoutPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -198,6 +198,7 @@ val themePatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -39,6 +39,7 @@ val alternativeThumbnailsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -33,6 +33,7 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -31,6 +31,7 @@ val autoRepeatPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -56,6 +56,7 @@ val backgroundPlaybackPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.debugging package app.revanced.patches.youtube.misc.debugging
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
@ -9,9 +10,15 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.applyMatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/EnableDebuggingPatch;"
@Suppress("unused") @Suppress("unused")
val enableDebuggingPatch = resourcePatch( val enableDebuggingPatch = bytecodePatch(
name = "Enable debugging", name = "Enable debugging",
description = "Adds options for debugging.", description = "Adds options for debugging.",
) { ) {
@ -21,9 +28,20 @@ val enableDebuggingPatch = resourcePatch(
addResourcesPatch, addResourcesPatch,
) )
compatibleWith("com.google.android.youtube") compatibleWith(
"com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
)
)
execute { val experimentalFeatureFlagParentMatch by experimentalFeatureFlagParentFingerprint()
execute { context ->
addResources("youtube", "misc.debugging.enableDebuggingPatch") addResources("youtube", "misc.debugging.enableDebuggingPatch")
PreferenceScreen.MISC.addPreferences( PreferenceScreen.MISC.addPreferences(
@ -38,5 +56,23 @@ val enableDebuggingPatch = resourcePatch(
), ),
), ),
) )
// Hook the method that looks up if a feature flag is active or not.
experimentalFeatureFlagFingerprint.applyMatch(
context,
experimentalFeatureFlagParentMatch
).mutableMethod.apply {
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
addInstructions(
insertIndex,
"""
move-result v0
invoke-static { p1, p2, v0 }, $EXTENSION_CLASS_DESCRIPTOR->isFeatureFlagEnabled(JZ)Z
move-result v0
return v0
"""
)
}
} }
} }

View File

@ -0,0 +1,17 @@
package app.revanced.patches.youtube.misc.debugging
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal val experimentalFeatureFlagParentFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("L")
parameters("L", "J", "[B")
strings("Unable to parse proto typed experiment flag: ")
}
internal val experimentalFeatureFlagFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Z")
parameters("J", "Z")
}

View File

@ -30,6 +30,7 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -20,6 +20,7 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -42,6 +42,7 @@ val spoofVideoStreamsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -40,6 +40,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )
} }

View File

@ -36,6 +36,7 @@ val bypassURLRedirectsPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -47,6 +47,7 @@ val openLinksExternallyPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.litho.filter package app.revanced.patches.youtube.misc.litho.filter
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -48,3 +49,17 @@ internal val emptyComponentFingerprint = fingerprint {
classDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1 classDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1
} }
} }
internal val lithoComponentNameUpbFeatureFlagFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Z")
parameters()
literal { 45631264L }
}
internal val lithoConverterBufferUpbFeatureFlagFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("L")
parameters("L")
literal { 45419603L }
}

View File

@ -13,6 +13,7 @@ import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_18_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_18_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
@ -41,6 +42,8 @@ val lithoFilterPatch = bytecodePatch(
val protobufBufferReferenceMatch by protobufBufferReferenceFingerprint() val protobufBufferReferenceMatch by protobufBufferReferenceFingerprint()
val readComponentIdentifierMatch by readComponentIdentifierFingerprint() val readComponentIdentifierMatch by readComponentIdentifierFingerprint()
val emptyComponentMatch by emptyComponentFingerprint() val emptyComponentMatch by emptyComponentFingerprint()
val lithoComponentNameUpbFeatureFlagMatch by lithoComponentNameUpbFeatureFlagFingerprint()
val lithoConverterBufferUpbFeatureFlagMatch by lithoConverterBufferUpbFeatureFlagFingerprint()
var filterCount = 0 var filterCount = 0
@ -135,9 +138,19 @@ val lithoFilterPatch = bytecodePatch(
builderMethodDescriptor.returnType == classDef.type builderMethodDescriptor.returnType == classDef.type
}!!.immutableClass.fields.single() }!!.immutableClass.fields.single()
// Returns an empty component instead of the original component.
fun createReturnEmptyComponentInstructions(register : Int) : String =
"""
move-object/from16 v$register, p1
invoke-static { v$register }, $builderMethodDescriptor
move-result-object v$register
iget-object v$register, v$register, $emptyComponentField
return-object v$register
"""
componentContextParserMatch.mutableMethod.apply { componentContextParserMatch.mutableMethod.apply {
// 19.18 and later require patching 2 methods instead of one. // 19.18 and later require patching 2 methods instead of one.
// Otherwise, the patched code is the same. // Otherwise the modifications done here are the same for all targets.
if (is_19_18_or_greater) { if (is_19_18_or_greater) {
// Get the method name of the ReadComponentIdentifierFingerprint call. // Get the method name of the ReadComponentIdentifierFingerprint call.
val readComponentMethodCallIndex = indexOfFirstInstructionOrThrow { val readComponentMethodCallIndex = indexOfFirstInstructionOrThrow {
@ -156,15 +169,11 @@ val lithoFilterPatch = bytecodePatch(
addInstructionsWithLabels( addInstructionsWithLabels(
insertHookIndex, insertHookIndex,
""" """
if-nez v$register, :unfiltered if-nez v$register, :unfiltered
# Component was filtered in ReadComponentIdentifierFingerprint hook # Component was filtered in ReadComponentIdentifierFingerprint hook
move-object/from16 v$register, p1 ${createReturnEmptyComponentInstructions(register)}
invoke-static { v$register }, $builderMethodDescriptor """,
move-result-object v$register
iget-object v$register, v$register, $emptyComponentField
return-object v$register
""",
ExternalLabel("unfiltered", getInstruction(insertHookIndex)), ExternalLabel("unfiltered", getInstruction(insertHookIndex)),
) )
} }
@ -190,20 +199,20 @@ val lithoFilterPatch = bytecodePatch(
).registerA ).registerA
// Find a free temporary register. // Find a free temporary register.
val register = getInstruction<OneRegisterInstruction>( val freeRegister = getInstruction<OneRegisterInstruction>(
// Immediately before is a StringBuilder append constant character. // Immediately before is a StringBuilder append constant character.
indexOfFirstInstructionReversedOrThrow(insertHookIndex, Opcode.CONST_16), indexOfFirstInstructionReversedOrThrow(insertHookIndex, Opcode.CONST_16),
).registerA ).registerA
// Verify the temp register will not clobber the method result register. // Verify the temp register will not clobber the method result register.
if (stringBuilderRegister == register) { if (stringBuilderRegister == freeRegister) {
throw PatchException("Free register will clobber StringBuilder register") throw PatchException("Free register will clobber StringBuilder register")
} }
val invokeFilterInstructions = """ val invokeFilterInstructions = """
invoke-static { v$identifierRegister, v$stringBuilderRegister }, $EXTENSION_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z invoke-static { v$identifierRegister, v$stringBuilderRegister }, $EXTENSION_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z
move-result v$register move-result v$freeRegister
if-eqz v$register, :unfiltered if-eqz v$freeRegister, :unfiltered
""" """
addInstructionsWithLabels( addInstructionsWithLabels(
@ -214,20 +223,14 @@ val lithoFilterPatch = bytecodePatch(
# Return null, and the ComponentContextParserFingerprint hook # Return null, and the ComponentContextParserFingerprint hook
# handles returning an empty component. # handles returning an empty component.
const/4 v$register, 0x0 const/4 v$freeRegister, 0x0
return-object v$register return-object v$freeRegister
""" """
} else { } else {
""" """
$invokeFilterInstructions $invokeFilterInstructions
# Exact same code as ComponentContextParserFingerprint hook, ${createReturnEmptyComponentInstructions(freeRegister)}
# but with the free register of this method.
move-object/from16 v$register, p1
invoke-static { v$register }, $builderMethodDescriptor
move-result-object v$register
iget-object v$register, v$register, $emptyComponentField
return-object v$register
""" """
}, },
ExternalLabel("unfiltered", getInstruction(insertHookIndex)), ExternalLabel("unfiltered", getInstruction(insertHookIndex)),
@ -235,6 +238,32 @@ val lithoFilterPatch = bytecodePatch(
} }
// endregion // endregion
// 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.
if (is_19_25_or_greater) {
lithoComponentNameUpbFeatureFlagMatch.mutableMethod.apply {
// Don't use return early, so the debug patch logs if this was originally on.
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN)
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction(insertIndex, "const/4 v$register, 0x0")
}
}
// Turn off a feature flag that enables native code of protobuf parsing (Upb protobuf).
// If this is enabled, then the litho protobuffer hook will always show an empty buffer
// since it's no longer handled by the hooked Java code.
lithoConverterBufferUpbFeatureFlagMatch.mutableMethod.apply {
val index = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstruction(index + 1, "const/4 v$register, 0x0")
}
// endregion
} }
finalize { finalize {

View File

@ -35,6 +35,7 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -42,6 +42,7 @@ val rememberVideoQualityPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )

View File

@ -24,6 +24,7 @@ val playbackSpeedPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )
} }

View File

@ -79,6 +79,7 @@ val restoreOldVideoQualityMenuPatch = bytecodePatch(
"19.16.39", "19.16.39",
"19.25.37", "19.25.37",
"19.34.42", "19.34.42",
"19.43.41",
), ),
) )