make it work with latest agp

This commit is contained in:
oSumAtrIX 2026-02-07 20:37:59 +01:00
parent 6fb4082bf8
commit e185702fd4
No known key found for this signature in database
GPG key ID: A9B3094ACDB604B4
3 changed files with 65 additions and 39 deletions

View file

@ -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)
}

View file

@ -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-><init>()V
new-instance v0, $classDescriptor
invoke-direct { v0 }, $classDescriptor-><init>()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()

View file

@ -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<MethodReference>()?.name == "<init>"
}
playerInitInsertRegister = playerInitMethod.getInstruction<FiveRegisterInstruction>(initThisIndex).registerC
playerInitInsertRegister =
playerInitMethod.getInstruction<FiveRegisterInstruction>(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<MethodReference>()?.name == "<init>"
}
mdxInitInsertRegister = mdxInitMethod.getInstruction<FiveRegisterInstruction>(initThisIndex).registerC
mdxInitInsertRegister =
mdxInitMethod.getInstruction<FiveRegisterInstruction>(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<OneRegisterInstruction>(videoLengthRegisterIndex).registerA
val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide
val videoLengthRegister =
getInstruction<OneRegisterInstruction>(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<TwoRegisterInstruction>(index).registerA
speedSelectionValueRegister =
getInstruction<TwoRegisterInstruction>(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<ReferenceInstruction>(0).reference
val setQualityFieldReference = it.getInstruction<ReferenceInstruction>(1).fieldReference!!
val onItemClickListenerClassReference =
it.getInstruction<ReferenceInstruction>(0).reference
val setQualityFieldReference =
it.getInstruction<ReferenceInstruction>(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.