fix(youtube): improve patching speed (#2514)

This commit is contained in:
LisoUseInAIKyrios
2023-06-28 17:43:45 +04:00
committed by GitHub
parent 23537557b5
commit 38dda9346b
71 changed files with 367 additions and 381 deletions
@@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object OnBackPressedFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
opcodes = listOf(
Opcode.RETURN_VOID
),
@@ -1,9 +1,14 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object RecyclerViewScrollingFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf(),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
@@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "Landroid/view/ViewGroup;", "Landroid/view/ViewGroup;"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
@@ -14,7 +18,4 @@ object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE
),
customFingerprint = { methodDef, _ ->
methodDef.name == "<init>"
}
)
@@ -1,6 +1,8 @@
package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
import org.jf.dexlib2.AccessFlags
/**
* Old API activity to embed YouTube into 3rd party Android apps.
@@ -10,6 +12,9 @@ import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.
* https://developers.google.com/youtube/android/player
*/
object StandalonePlayerActivityFingerprint : IntegrationsFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/youtube/api/StandalonePlayerActivity;"
&& methodDef.name == "onCreate"
@@ -9,5 +9,5 @@ object ComponentContextParserFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE
),
strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings")
strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings.")
)
@@ -1,11 +1,13 @@
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object LithoFilterFingerprint : MethodFingerprint(
customFingerprint = custom@{ method, classDef ->
if (method.name != "<clinit>") return@custom false
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
returnType = "V",
customFingerprint = { _, classDef ->
classDef.type.endsWith("LithoFilterPatch;")
}
)
@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC,
@@ -1,16 +1,14 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2)
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
@@ -0,0 +1,14 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
/**
* Class fingerprint for [MinimizedPlaybackSettingsFingerprint]
*/
object MinimizedPlaybackSettingsParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("Landroid/content/Context;", "Landroid/support/v4/media/session/MediaSessionCompat"),
strings = listOf("sessionToken must not be null")
)
@@ -8,6 +8,7 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
@@ -21,6 +22,7 @@ import app.revanced.patches.youtube.misc.minimizedplayback.annotations.Minimized
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsParentFingerprint
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@@ -35,7 +37,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
class MinimizedPlaybackPatch : BytecodePatch(
listOf(
MinimizedPlaybackManagerFingerprint,
MinimizedPlaybackSettingsFingerprint,
MinimizedPlaybackSettingsParentFingerprint,
KidsMinimizedPlaybackPolicyControllerFingerprint
)
) {
@@ -60,6 +62,8 @@ class MinimizedPlaybackPatch : BytecodePatch(
} ?: return MinimizedPlaybackManagerFingerprint.toErrorResult()
// Enable minimized playback option in YouTube settings
MinimizedPlaybackSettingsParentFingerprint.result ?: return MinimizedPlaybackSettingsParentFingerprint.toErrorResult()
MinimizedPlaybackSettingsFingerprint.resolve(context, MinimizedPlaybackSettingsParentFingerprint.result!!.classDef)
MinimizedPlaybackSettingsFingerprint.result?.apply {
val booleanCalls = method.implementation!!.instructions.withIndex()
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
@@ -5,42 +5,33 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("player-controls-bytecode-patch")
@DependsOn([ResourceMappingPatch::class])
@DependsOn([BottomControlsResourcePatch::class])
@Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility
@Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch(
listOf(PlayerControlsVisibilityFingerprint)
listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
bottomUiContainerResourceId = ResourceMappingPatch
.resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
// TODO: another solution is required, this is hacky
listOf(BottomControlsInflateFingerprint).resolve(context, context.classes)
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
return PatchResultSuccess()
}
internal companion object {
var bottomUiContainerResourceId: Long = 0
lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult
@@ -1,21 +1,19 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object BottomControlsInflateFingerprint : MethodFingerprint(
object BottomControlsInflateFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
returnType = "L",
parameters = listOf(),
opcodes = listOf(
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT
),
customFingerprint = { methodDef, _ ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == PlayerControlsBytecodePatch.bottomUiContainerResourceId
} == true
}
literal = BottomControlsResourcePatch.bottomUiContainerResourceId
)
@@ -1,10 +1,12 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object PlayerControlsVisibilityFingerprint : MethodFingerprint(
"V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Z", "Z"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
@@ -8,22 +8,30 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import java.io.Closeable
@Name("bottom-controls-resource-patch")
@Description("Manages the resources for the bottom controls of the YouTube player.")
@PlayerControlsCompatibility
@DependsOn([ResourceMappingPatch::class])
@Version("0.0.1")
class BottomControlsResourcePatch : ResourcePatch, Closeable {
override fun execute(context: ResourceContext): PatchResult {
resourceContext = context
targetXmlEditor = context.xmlEditor[TARGET_RESOURCE]
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
return PatchResultSuccess()
}
companion object {
internal var bottomUiContainerResourceId : Long = -1
internal const val TARGET_RESOURCE_NAME = "youtube_controls_bottom_ui_container.xml"
private const val TARGET_RESOURCE = "res/layout/$TARGET_RESOURCE_NAME"
@@ -33,8 +41,6 @@ class BottomControlsResourcePatch : ResourcePatch, Closeable {
// The element to which to add the new elements to
private var lastLeftOf = "fullscreen_button"
/**
* Add new controls to the bottom of the YouTube player.
* @param hostYouTubeControlsBottomUiResourceName The hosting resource name containing the elements.
@@ -1,8 +1,13 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object LicenseActivityFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("LicenseActivity;") && methodDef.name == "onCreate"
}
@@ -1,20 +1,15 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object SetThemeFingerprint : MethodFingerprint(
object SetThemeFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "L",
parameters = listOf(),
opcodes = listOf(Opcode.RETURN_OBJECT),
customFingerprint = { methodDef, _ ->
methodDef.implementation?.instructions?.any { instruction ->
if (instruction.opcode != Opcode.CONST) return@any false
val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
SettingsResourcePatch.appearanceStringId == wideLiteral
} ?: false
}
literal = SettingsResourcePatch.appearanceStringId
)