diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt deleted file mode 100644 index 16b9f9472..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.music.layout.upgradebutton.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 PivotBarConstructorFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = listOf("L", "Z"), - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.NOP, - Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt deleted file mode 100644 index 614953027..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt +++ /dev/null @@ -1,104 +0,0 @@ -package app.revanced.patches.music.layout.upgradebutton.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.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -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.toInstructions -import app.revanced.patches.music.layout.upgradebutton.fingerprints.* -import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch -import app.revanced.patches.music.misc.resourceid.patch.SharedResourceIdPatch -import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility -import app.revanced.util.integrations.Constants.INTEGRATIONS_PATH -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction22t -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.formats.Instruction22c -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - -@Patch -@Name("hide-upgrade-button") -@Description("Remove upgrade tab from pivot bar, hide upgrade banner from homepage.") -@DependsOn( - [ - MusicIntegrationsPatch::class, - SharedResourceIdPatch::class - ] -) -@YouTubeMusicCompatibility -@Version("0.0.1") -class RemoveUpgradeButtonPatch : BytecodePatch( - listOf( - PivotBarConstructorFingerprint, - NotifierShelfFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = PivotBarConstructorFingerprint.result?: return PivotBarConstructorFingerprint.toErrorResult() - val implementation = result.mutableMethod.implementation!! - - val pivotBarElementFieldRef = - (implementation.instructions[result.scanResult.patternScanResult!!.endIndex - 1] as Instruction22c).reference - - val register = (implementation.instructions.first() as Instruction35c).registerC - // first compile all the needed instructions - val instructionList = """ - invoke-interface { v0 }, Ljava/util/List;->size()I - move-result v1 - const/4 v2, 0x3 - invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; - iput-object v0, v$register, $pivotBarElementFieldRef - """.toInstructions().toMutableList() - - - val endIndex = result.scanResult.patternScanResult!!.endIndex - - // replace the instruction to retain the label at given index - implementation.replaceInstruction( - endIndex - 1, instructionList[0] // invoke-interface - ) - // do not forget to remove this instruction since we added it already - instructionList.removeFirst() - - val exitInstruction = instructionList.last() // iput-object - implementation.addInstruction( - endIndex, exitInstruction - ) - // do not forget to remove this instruction since we added it already - instructionList.removeLast() - - // add the necessary if statement to remove the upgrade tab button in case it exists - instructionList.add( - 2, // if-le - BuilderInstruction22t( - Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex) - ) - ) - - implementation.addInstructions( - endIndex, instructionList - ) - - NotifierShelfFingerprint.result?.let { - with (it.mutableMethod) { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = (instruction(targetIndex) as OneRegisterInstruction).registerA - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $INTEGRATIONS_PATH/adremover/AdRemoverAPI;->HideViewWithLayout1dp(Landroid/view/View;)V" - ) - } - } ?: return NotifierShelfFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/NotifierShelfFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/NotifierShelfFingerprint.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/NotifierShelfFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/NotifierShelfFingerprint.kt index d2167de42..07ec13974 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/NotifierShelfFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/NotifierShelfFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.layout.upgradebutton.fingerprints +package app.revanced.patches.music.misc.upgradebutton.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt new file mode 100644 index 000000000..8e6f8c2e8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.music.misc.upgradebutton.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 +import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction + +object PivotBarConstructorFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + opcodes = listOf( + Opcode.IPUT_OBJECT, + Opcode.RETURN_VOID + ), + customFingerprint = { methodDef -> + methodDef.name == "" + && methodDef.implementation!!.instructions.any { + ((it as? NarrowLiteralInstruction)?.narrowLiteral == 117501096) + } + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/patch/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/patch/RemoveUpgradeButtonPatch.kt new file mode 100644 index 000000000..75c290d42 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/upgradebutton/patch/RemoveUpgradeButtonPatch.kt @@ -0,0 +1,91 @@ +package app.revanced.patches.music.misc.upgradebutton.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.extensions.addInstruction +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.instruction +import app.revanced.patcher.extensions.replaceInstruction +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.patches.music.misc.integrations.patch.MusicIntegrationsPatch +import app.revanced.patches.music.misc.resourceid.patch.SharedResourceIdPatch +import app.revanced.patches.music.misc.upgradebutton.fingerprints.* +import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility +import app.revanced.util.integrations.Constants.INTEGRATIONS_PATH +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction +import org.jf.dexlib2.iface.reference.FieldReference + +@Patch +@Name("hide-upgrade-button") +@Description("Remove upgrade tab from pivot bar, hide upgrade banner from homepage.") +@DependsOn( + [ + MusicIntegrationsPatch::class, + SharedResourceIdPatch::class + ] +) +@YouTubeMusicCompatibility +@Version("0.0.1") +class RemoveUpgradeButtonPatch : BytecodePatch( + listOf( + PivotBarConstructorFingerprint, + NotifierShelfFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + PivotBarConstructorFingerprint.result?.let { + with (it.mutableMethod) { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + + val targetRegisterA = (instruction(targetIndex) as TwoRegisterInstruction).registerA + val targetRegisterB = (instruction(targetIndex) as TwoRegisterInstruction).registerB + + val replaceReference = + (instruction(targetIndex) as ReferenceInstruction).reference as FieldReference + + val replaceReferenceToCall = replaceReference.definingClass + + "->" + + replaceReference.name + + ":" + + replaceReference.type + + replaceInstruction( + targetIndex, + "invoke-interface {v$targetRegisterA}, Ljava/util/List;->size()I" + ) + addInstructions( + targetIndex + 1,""" + move-result v1 + const/4 v2, 0x3 + if-le v1, v2, :dismiss + invoke-interface {v$targetRegisterA, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; + :dismiss + iput-object v$targetRegisterA, v$targetRegisterB, $replaceReferenceToCall + """ + ) + } + } ?: return PivotBarConstructorFingerprint.toErrorResult() + + NotifierShelfFingerprint.result?.let { + with (it.mutableMethod) { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = (instruction(targetIndex) as OneRegisterInstruction).registerA + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $INTEGRATIONS_PATH/adremover/AdRemoverAPI;->HideViewWithLayout1dp(Landroid/view/View;)V" + ) + } + } ?: return NotifierShelfFingerprint.toErrorResult() + + return PatchResultSuccess() + } +}