From 89358f86a0d88f567c09cc210f86684767467fa6 Mon Sep 17 00:00:00 2001 From: inotia00 Date: Tue, 20 Jun 2023 14:42:38 +0900 Subject: [PATCH] feat(music/enable-opus-codec): change to abstract patch --- .../fingerprints/AllCodecsFingerprint.kt | 18 ----- .../misc/codecs/patch/CodecsUnlockPatch.kt | 50 +------------ .../CodecReferenceFingerprint.kt} | 8 +- .../fingerprints/CodecSelectorFingerprint.kt} | 4 +- .../patch/opus/AbstractOpusCodecsPatch.kt | 75 +++++++++++++++++++ 5 files changed, 84 insertions(+), 71 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsFingerprint.kt rename src/main/kotlin/app/revanced/patches/{music/misc/codecs/fingerprints/AllCodecsParentFingerprint.kt => shared/fingerprints/CodecReferenceFingerprint.kt} (64%) rename src/main/kotlin/app/revanced/patches/{music/misc/codecs/fingerprints/CodecsLockFingerprint.kt => shared/fingerprints/CodecSelectorFingerprint.kt} (80%) create mode 100644 src/main/kotlin/app/revanced/patches/shared/patch/opus/AbstractOpusCodecsPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsFingerprint.kt deleted file mode 100644 index 2677b2b4a..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.music.misc.codecs.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 AllCodecsFingerprint : MethodFingerprint( - returnType = "J", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.INVOKE_STATIC - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/codecs/patch/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/codecs/patch/CodecsUnlockPatch.kt index 09aeabb70..df08d8a62 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/codecs/patch/CodecsUnlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/codecs/patch/CodecsUnlockPatch.kt @@ -1,29 +1,18 @@ package app.revanced.patches.music.misc.codecs.patch -import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -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 import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.misc.codecs.fingerprints.AllCodecsFingerprint -import app.revanced.patches.music.misc.codecs.fingerprints.AllCodecsParentFingerprint -import app.revanced.patches.music.misc.codecs.fingerprints.CodecsLockFingerprint import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility +import app.revanced.patches.shared.patch.opus.AbstractOpusCodecsPatch import app.revanced.util.enum.CategoryType import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Patch @Name("enable-opus-codec") @@ -31,45 +20,14 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @DependsOn([MusicSettingsPatch::class]) @YouTubeMusicCompatibility @Version("0.0.1") -class CodecsUnlockPatch : BytecodePatch( - listOf( - AllCodecsParentFingerprint, - CodecsLockFingerprint - ) +class CodecsUnlockPatch : AbstractOpusCodecsPatch( + "$MUSIC_MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z" ) { override fun execute(context: BytecodeContext): PatchResult { - - AllCodecsParentFingerprint.result?.let { parentResult -> - AllCodecsFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { - allCodecsMethod = context.toMethodWalker(it.method) - .nextMethod(it.scanResult.patternScanResult!!.endIndex) - .getMethod() - - } ?: return AllCodecsFingerprint.toErrorResult() - } ?: return AllCodecsParentFingerprint.toErrorResult() - - CodecsLockFingerprint.result?.let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - addInstructionsWithLabels( - targetIndex + 1, """ - invoke-static {}, $MUSIC_MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z - move-result v7 - if-eqz v7, :mp4a - invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set; - move-result-object v$targetRegister - """, ExternalLabel("mp4a", getInstruction(targetIndex + 1)) - ) - } - } ?: return CodecsLockFingerprint.toErrorResult() + super.execute(context) MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_enable_opus_codec", "true") return PatchResultSuccess() } - - private companion object { - lateinit var allCodecsMethod: Method - } } diff --git a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecReferenceFingerprint.kt similarity index 64% rename from src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecReferenceFingerprint.kt index 88e327cd8..a52b395cf 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/AllCodecsParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecReferenceFingerprint.kt @@ -1,16 +1,14 @@ -package app.revanced.patches.music.misc.codecs.fingerprints +package app.revanced.patches.shared.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 AllCodecsParentFingerprint : MethodFingerprint( +object CodecReferenceFingerprint : MethodFingerprint( returnType = "J", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L"), - opcodes = listOf( - Opcode.INVOKE_SUPER - ), + opcodes = listOf(Opcode.INVOKE_SUPER), strings = listOf("itag") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/CodecsLockFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecSelectorFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/CodecsLockFingerprint.kt rename to src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecSelectorFingerprint.kt index 95ecf01b6..8fd0539d5 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/codecs/fingerprints/CodecsLockFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/CodecSelectorFingerprint.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.music.misc.codecs.fingerprints +package app.revanced.patches.shared.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 CodecsLockFingerprint : MethodFingerprint( +object CodecSelectorFingerprint : MethodFingerprint( returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf( diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/opus/AbstractOpusCodecsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/opus/AbstractOpusCodecsPatch.kt new file mode 100644 index 000000000..c4a51d5e3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/patch/opus/AbstractOpusCodecsPatch.kt @@ -0,0 +1,75 @@ +package app.revanced.patches.shared.patch.opus + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultError +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.fingerprints.CodecReferenceFingerprint +import app.revanced.patches.shared.fingerprints.CodecSelectorFingerprint +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.reference.Reference + +@Name("abstract-opus-codec") +@Version("0.0.1") +abstract class AbstractOpusCodecsPatch( + private val descriptor: String +) : BytecodePatch( + listOf( + CodecReferenceFingerprint, + CodecSelectorFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + + CodecReferenceFingerprint.result?.mutableMethod?.let { + it.implementation!!.instructions.apply { + var targetIndex = 0 + for ((index, instruction) in withIndex()) { + if (instruction.opcode != Opcode.INVOKE_STATIC) continue + + val targetParameter = it.getInstruction(index).reference + + if (targetParameter.toString().endsWith("Ljava/util/Set;")) { + targetReference = targetParameter + targetIndex = index + break + } + } + if (targetIndex == 0) + throw PatchResultError("Target method not found!") + } + } ?: return CodecReferenceFingerprint.toErrorResult() + + CodecSelectorFingerprint.result?.let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstructionsWithLabels( + targetIndex + 1, """ + invoke-static {}, $descriptor + move-result v7 + if-eqz v7, :mp4a + invoke-static {}, $targetReference + move-result-object v$targetRegister + """, ExternalLabel("mp4a", getInstruction(targetIndex + 1)) + ) + } + } ?: return CodecSelectorFingerprint.toErrorResult() + + return PatchResultSuccess() + } + + companion object { + lateinit var targetReference: Reference + } +}