make it work with latest agp
This commit is contained in:
parent
6fb4082bf8
commit
e185702fd4
3 changed files with 65 additions and 39 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue