From e185702fd4b35ae8531f32bbb6bcdbe2b988b7e0 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 7 Feb 2026 20:37:59 +0100 Subject: [PATCH] make it work with latest agp --- .../shared/misc/litho/filter/Fingerprints.kt | 2 +- .../misc/litho/filter/LithoFilterPatch.kt | 31 +++++--- .../information/VideoInformationPatch.kt | 71 ++++++++++++------- 3 files changed, 65 insertions(+), 39 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/Fingerprints.kt index 4c68fc5e1d..d69737d876 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.lithoFilterMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.lithoFilterInitMethod by gettingFirstMethodDeclaratively { definingClass { endsWith("/LithoFilterPatch;") } accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/LithoFilterPatch.kt index 205c47a9cb..fcc830c95c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/litho/filter/LithoFilterPatch.kt @@ -31,7 +31,8 @@ lateinit var addLithoFilter: (String) -> Unit */ private var filterCount = 0 -internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/shared/patches/litho/LithoFilterPatch;" +internal const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/shared/patches/litho/LithoFilterPatch;" /** * A patch that allows to filter Litho components based on their identifier or path. @@ -96,17 +97,24 @@ internal fun lithoFilterPatch( apply { // Remove dummy filter from extenion static field // and add the filters included during patching. - lithoFilterMethod.apply { - removeInstructions(2, 4) // Remove dummy filter. + lithoFilterInitMethod.apply { + // Remove the array initialization with the dummy filter. + removeInstructions(6) + addInstructions( + 0, + "new-array v1, v1, [Lapp/revanced/extension/shared/patches/litho/Filter;" + ) + + // Fill the array with the filters added during patching. addLithoFilter = { classDescriptor -> addInstructions( - 2, + 1, """ - new-instance v1, $classDescriptor - invoke-direct { v1 }, $classDescriptor->()V + new-instance v0, $classDescriptor + invoke-direct { v0 }, $classDescriptor->()V const/16 v2, ${filterCount++} - aput-object v1, v0, v2 + aput-object v0, v1, v2 """, ) } @@ -114,7 +122,7 @@ internal fun lithoFilterPatch( // Tell the extension whether to extract the identifier from the buffer. if (getExtractIdentifierFromBuffer()) { - lithoFilterMethod.classDef.fields.first { it.name == "EXTRACT_IDENTIFIER_FROM_BUFFER" } + lithoFilterInitMethod.classDef.fields.first { it.name == "EXTRACT_IDENTIFIER_FROM_BUFFER" } .initialValue = ImmutableBooleanEncodedValue.forBoolean(true).toMutable() } @@ -138,7 +146,7 @@ internal fun lithoFilterPatch( // Find class and methods to create an empty component. val builderMethodDescriptor = emptyComponentMethod.immutableClassDef.methods.single { - // The only static method in the class. + // The only static method in the class. method -> AccessFlags.STATIC.isSet(method.accessFlags) } @@ -203,8 +211,9 @@ internal fun lithoFilterPatch( } afterDependents { - // Save the number of filters added. - lithoFilterMethod.replaceInstruction(0, "const/16 v0, $filterCount") + // Set the array size to the actual filter count of the array + // initialized at the beginning of the patch. + lithoFilterInitMethod.addInstructions(0, "const/16 v1, $filterCount") } block() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index 697853819c..b8bd0a4f57 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -39,7 +39,8 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.util.MethodUtil -private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/VideoInformation;" +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/VideoInformation;" private const val EXTENSION_PLAYER_INTERFACE = "Lapp/revanced/extension/youtube/patches/VideoInformation\$PlaybackController;" private const val EXTENSION_VIDEO_QUALITY_MENU_INTERFACE = @@ -99,7 +100,8 @@ val videoInformationPatch = bytecodePatch( val initThisIndex = playerInitMethod.indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_DIRECT && getReference()?.name == "" } - playerInitInsertRegister = playerInitMethod.getInstruction(initThisIndex).registerC + playerInitInsertRegister = + playerInitMethod.getInstruction(initThisIndex).registerC playerInitInsertIndex = initThisIndex + 1 // Create extension interface methods. @@ -116,7 +118,8 @@ val videoInformationPatch = bytecodePatch( val initThisIndex = mdxInitMethod.indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_DIRECT && getReference()?.name == "" } - mdxInitInsertRegister = mdxInitMethod.getInstruction(initThisIndex).registerC + mdxInitInsertRegister = + mdxInitMethod.getInstruction(initThisIndex).registerC mdxInitInsertIndex = initThisIndex + 1 // Hook the MDX director for use through the extension. @@ -134,13 +137,15 @@ val videoInformationPatch = bytecodePatch( videoLengthMethodMatch.method.apply { val videoLengthRegisterIndex = videoLengthMethodMatch[-1] - 2 - val videoLengthRegister = getInstruction(videoLengthRegisterIndex).registerA - val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide + val videoLengthRegister = + getInstruction(videoLengthRegisterIndex).registerA + val dummyRegisterForLong = + videoLengthRegister + 1 // Required for long values since they are wide. addInstruction( videoLengthMethodMatch[-1], "invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, " + - "$EXTENSION_CLASS_DESCRIPTOR->setVideoLength(J)V", + "$EXTENSION_CLASS_DESCRIPTOR->setVideoLength(J)V", ) } } @@ -162,7 +167,7 @@ val videoInformationPatch = bytecodePatch( addPlayerResponseMethodHook( Hook.ProtoBufferParameterBeforeVideoId( "$EXTENSION_CLASS_DESCRIPTOR->" + - "newPlayerResponseSignature(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;", + "newPlayerResponseSignature(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;", ), ) @@ -276,7 +281,8 @@ val videoInformationPatch = bytecodePatch( speedSelectionInsertMethod = this speedSelectionInsertIndex = index + 1 - speedSelectionValueRegister = getInstruction(index).registerA + speedSelectionValueRegister = + getInstruction(index).registerA } } @@ -350,8 +356,10 @@ val videoInformationPatch = bytecodePatch( videoQualitySetterMethod.immutableClassDef.getSetVideoQualityMethod().let { it // This instruction refers to the field with the type that contains the setQuality method. - val onItemClickListenerClassReference = it.getInstruction(0).reference - val setQualityFieldReference = it.getInstruction(1).fieldReference!! + val onItemClickListenerClassReference = + it.getInstruction(0).reference + val setQualityFieldReference = + it.getInstruction(1).fieldReference!! firstClassDef(setQualityFieldReference.type).apply { // Add interface and helper methods to allow extension code to call obfuscated methods. @@ -404,7 +412,11 @@ val videoInformationPatch = bytecodePatch( } } -private fun addSeekInterfaceMethods(targetClass: MutableClassDef, seekToMethod: Method, seekToRelativeMethod: Method) { +private fun addSeekInterfaceMethods( + targetClass: MutableClassDef, + seekToMethod: Method, + seekToRelativeMethod: Method +) { // Add the interface and methods that extension calls. targetClass.interfaces.add(EXTENSION_PLAYER_INTERFACE) @@ -452,9 +464,11 @@ private fun addSeekInterfaceMethods(targetClass: MutableClassDef, seekToMethod: } } -private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) = addInstruction(insertIndex, "invoke-static { $register }, $descriptor") +private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) = + addInstruction(insertIndex, "invoke-static { $register }, $descriptor") -private fun MutableMethod.insertTimeHook(insertIndex: Int, descriptor: String) = insert(insertIndex, "p1, p2", descriptor) +private fun MutableMethod.insertTimeHook(insertIndex: Int, descriptor: String) = + insert(insertIndex, "p1, p2", descriptor) /** * Hook the player controller. Called when a video is opened or the current video is changed. @@ -465,11 +479,12 @@ private fun MutableMethod.insertTimeHook(insertIndex: Int, descriptor: String) = * @param targetMethodClass The descriptor for the class to invoke when the player controller is created. * @param targetMethodName The name of the static method to invoke when the player controller is created. */ -internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = playerInitMethod.insert( - playerInitInsertIndex++, - "v$playerInitInsertRegister", - "$targetMethodClass->$targetMethodName($EXTENSION_PLAYER_INTERFACE)V", -) +internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = + playerInitMethod.insert( + playerInitInsertIndex++, + "v$playerInitInsertRegister", + "$targetMethodClass->$targetMethodName($EXTENSION_PLAYER_INTERFACE)V", + ) /** * Hook the MDX player director. Called when playing videos while casting to a big screen device. @@ -477,11 +492,12 @@ internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = * @param targetMethodClass The descriptor for the class to invoke when the player controller is created. * @param targetMethodName The name of the static method to invoke when the player controller is created. */ -internal fun onCreateHookMdx(targetMethodClass: String, targetMethodName: String) = mdxInitMethod.insert( - mdxInitInsertIndex++, - "v$mdxInitInsertRegister", - "$targetMethodClass->$targetMethodName($EXTENSION_PLAYER_INTERFACE)V", -) +internal fun onCreateHookMdx(targetMethodClass: String, targetMethodName: String) = + mdxInitMethod.insert( + mdxInitInsertIndex++, + "v$mdxInitInsertRegister", + "$targetMethodClass->$targetMethodName($EXTENSION_PLAYER_INTERFACE)V", + ) /** * Hook the video time. @@ -498,10 +514,11 @@ fun videoTimeHook(targetMethodClass: String, targetMethodName: String) = timeMet /** * Hook when the video speed is changed for any reason _except when the user manually selects a new speed_. */ -fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) = setPlaybackSpeedMethod.addInstruction( - setPlaybackSpeedMethodIndex++, - "invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V", -) +fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) = + setPlaybackSpeedMethod.addInstruction( + setPlaybackSpeedMethodIndex++, + "invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V", + ) /** * Hook the video speed selected by the user.