fix(YouTube Music): Fix compatibility with latest versions (#2924)
This commit is contained in:
parent
497c067e80
commit
8378c84816
|
@ -302,6 +302,12 @@ public final class app/revanced/patches/moneymanager/UnlockProPatch : app/revanc
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/music/ad/video/HideMusicVideoAds : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/music/ad/video/HideMusicVideoAds;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/music/ad/video/MusicVideoAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/music/ad/video/MusicVideoAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/music/ad/video/MusicVideoAdsPatch;
|
public static final field INSTANCE Lapp/revanced/patches/music/ad/video/MusicVideoAdsPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
@ -314,6 +320,12 @@ public final class app/revanced/patches/music/audio/codecs/CodecsUnlockPatch : a
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch;
|
public static final field INSTANCE Lapp/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
@ -326,6 +338,12 @@ public final class app/revanced/patches/music/interaction/permanentrepeat/Perman
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch;
|
public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
@ -338,6 +356,12 @@ public final class app/revanced/patches/music/layout/compactheader/CompactHeader
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/music/layout/compactheader/HideCategoryBar : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/music/layout/compactheader/HideCategoryBar;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch;
|
public static final field INSTANCE Lapp/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package app.revanced.patches.music.ad.video
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsParentFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Hide music video ads",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object HideMusicVideoAds : BytecodePatch(
|
||||||
|
setOf(ShowMusicVideoAdsParentFingerprint),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
ShowMusicVideoAdsParentFingerprint.result?.let {
|
||||||
|
val showMusicVideoAdsMethod = context
|
||||||
|
.toMethodWalker(it.mutableMethod)
|
||||||
|
.nextMethod(it.scanResult.patternScanResult!!.startIndex + 1, true).getMethod() as MutableMethod
|
||||||
|
|
||||||
|
showMusicVideoAdsMethod.addInstruction(0, "const/4 p1, 0x0")
|
||||||
|
} ?: throw ShowMusicVideoAdsParentFingerprint.exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("This patch class has been renamed to HideMusicVideoAds.")
|
||||||
|
object MusicVideoAdsPatch : BytecodePatch(
|
||||||
|
dependencies = setOf(HideMusicVideoAds::class),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
package app.revanced.patches.music.ad.video
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint
|
|
||||||
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
name = "Music video ads",
|
|
||||||
description = "Removes ads in the music player.",
|
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
|
||||||
)
|
|
||||||
@Suppress("unused")
|
|
||||||
object MusicVideoAdsPatch : BytecodePatch(
|
|
||||||
setOf(ShowMusicVideoAdsConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
|
|
||||||
|
|
||||||
val result = ShowMusicVideoAdsFingerprint.result!!
|
|
||||||
|
|
||||||
result.mutableMethod.addInstruction(
|
|
||||||
result.scanResult.patternScanResult!!.startIndex,
|
|
||||||
"""
|
|
||||||
const/4 p1, 0x0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package app.revanced.patches.music.ad.video.fingerprints
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
|
|
||||||
internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
|
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf(
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.NEW_INSTANCE,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.NEW_INSTANCE,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.NEW_INSTANCE,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IPUT_BOOLEAN,
|
|
||||||
Opcode.RETURN_VOID
|
|
||||||
)
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
package app.revanced.patches.music.ad.video.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object ShowMusicVideoAdsFingerprint : MethodFingerprint(
|
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf(
|
|
||||||
Opcode.IPUT_BOOLEAN,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.RETURN_VOID
|
|
||||||
)
|
|
||||||
)
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package app.revanced.patches.music.ad.video.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object ShowMusicVideoAdsParentFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
),
|
||||||
|
strings = listOf("maybeRegenerateCpnAndStatsClient called unexpectedly, but no error."),
|
||||||
|
)
|
|
@ -10,13 +10,12 @@ import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprin
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Codecs unlock",
|
|
||||||
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.",
|
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Deprecated("This patch is no longer needed as the feature is now enabled by default.")
|
||||||
object CodecsUnlockPatch : BytecodePatch(
|
object CodecsUnlockPatch : BytecodePatch(
|
||||||
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint)
|
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val codecsLockResult = CodecsLockFingerprint.result!!
|
val codecsLockResult = CodecsLockFingerprint.result!!
|
||||||
|
@ -25,13 +24,13 @@ object CodecsUnlockPatch : BytecodePatch(
|
||||||
|
|
||||||
val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex
|
val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex
|
||||||
val instructionIndex = scanResultStartIndex +
|
val instructionIndex = scanResultStartIndex +
|
||||||
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
|
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
|
||||||
// for 5.16.xx and lower
|
// for 5.16.xx and lower
|
||||||
-3
|
-3
|
||||||
} else {
|
} else {
|
||||||
// since 5.17.xx
|
// since 5.17.xx
|
||||||
-2
|
-2
|
||||||
}
|
}
|
||||||
|
|
||||||
val allCodecsResult = AllCodecsReferenceFingerprint.result!!
|
val allCodecsResult = AllCodecsReferenceFingerprint.result!!
|
||||||
val allCodecsMethod =
|
val allCodecsMethod =
|
||||||
|
@ -41,7 +40,7 @@ object CodecsUnlockPatch : BytecodePatch(
|
||||||
|
|
||||||
implementation.replaceInstruction(
|
implementation.replaceInstruction(
|
||||||
instructionIndex,
|
instructionIndex,
|
||||||
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
|
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,36 @@
|
||||||
package app.revanced.patches.music.audio.exclusiveaudio
|
package app.revanced.patches.music.audio.exclusiveaudio
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AllowExclusiveAudioPlaybackFingerprint
|
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AllowExclusiveAudioPlaybackFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Exclusive audio playback",
|
name = "Enable exclusive audio playback",
|
||||||
description = "Enables the option to play audio without video.",
|
description = "Enables the option to play audio without video.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ExclusiveAudioPatch : BytecodePatch(
|
object EnableExclusiveAudioPlayback : BytecodePatch(
|
||||||
setOf(AllowExclusiveAudioPlaybackFingerprint)
|
setOf(AllowExclusiveAudioPlaybackFingerprint),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply {
|
AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply {
|
||||||
addInstructions(
|
addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
const/4 v0, 0x1
|
const/4 v0, 0x1
|
||||||
return v0
|
return v0
|
||||||
"""
|
""",
|
||||||
)
|
)
|
||||||
} ?: throw AllowExclusiveAudioPlaybackFingerprint.exception
|
} ?: throw AllowExclusiveAudioPlaybackFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("This patch class has been renamed to EnableExclusiveAudioPlayback.")
|
||||||
|
object ExclusiveAudioPatch : BytecodePatch(emptySet()) {
|
||||||
|
override fun execute(context: BytecodeContext) = EnableExclusiveAudioPlayback.execute(context)
|
||||||
|
}
|
|
@ -1,25 +1,32 @@
|
||||||
package app.revanced.patches.music.interaction.permanentshuffle
|
package app.revanced.patches.music.interaction.permanentshuffle
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.music.interaction.permanentshuffle.fingerprints.DisableShuffleFingerprint
|
import app.revanced.patches.music.interaction.permanentshuffle.fingerprints.DisableShuffleFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Permanent shuffle",
|
name = "Permanent shuffle",
|
||||||
description = "Permanently remember your shuffle preference " +
|
description = "Permanently remember your shuffle preference " +
|
||||||
"even if the playlist ends or another track is played.",
|
"even if the playlist ends or another track is played.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
use = false
|
use = false,
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object PermanentShuffleTogglePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
|
object PermanentShufflePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
DisableShuffleFingerprint.result?.mutableMethod?.addInstruction(0, "return-void")
|
DisableShuffleFingerprint.result?.mutableMethod?.addInstruction(0, "return-void")
|
||||||
?: throw DisableShuffleFingerprint.exception
|
?: throw DisableShuffleFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("This patch class has been renamed to PermanentShufflePatch.")
|
||||||
|
object PermanentShuffleTogglePatch : BytecodePatch(
|
||||||
|
dependencies = setOf(PermanentShufflePatch::class),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package app.revanced.patches.music.layout.compactheader
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patches.music.layout.compactheader.fingerprints.CompactHeaderConstructorFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11x
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
name = "Compact header",
|
|
||||||
description = "Hides the music category bar at the top of the homepage.",
|
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
|
||||||
use = false
|
|
||||||
)
|
|
||||||
@Suppress("unused")
|
|
||||||
object CompactHeaderPatch : BytecodePatch(
|
|
||||||
setOf(CompactHeaderConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
val result = CompactHeaderConstructorFingerprint.result!!
|
|
||||||
val method = result.mutableMethod
|
|
||||||
|
|
||||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
|
||||||
val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA
|
|
||||||
method.addInstructions(
|
|
||||||
insertIndex, """
|
|
||||||
const/16 v2, 0x8
|
|
||||||
invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package app.revanced.patches.music.layout.compactheader
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.music.layout.compactheader.fingerprints.ConstructCategoryBarFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Hide category bar",
|
||||||
|
description = "Hides the category bar at the top of the homepage.",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
|
use = false,
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object HideCategoryBar : BytecodePatch(
|
||||||
|
setOf(ConstructCategoryBarFingerprint),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
ConstructCategoryBarFingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
const/16 v2, 0x8
|
||||||
|
invoke-virtual {v$register, v2}, Landroid/view/View;->setVisibility(I)V
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw ConstructCategoryBarFingerprint.exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("This patch class has been renamed to HideCategoryBar.")
|
||||||
|
object CompactHeaderPatch : BytecodePatch(
|
||||||
|
dependencies = setOf(HideCategoryBar::class),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,19 +5,19 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object CompactHeaderConstructorFingerprint : MethodFingerprint(
|
internal object ConstructCategoryBarFingerprint : MethodFingerprint(
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L"), listOf(
|
"V",
|
||||||
Opcode.INVOKE_DIRECT,
|
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
Opcode.IPUT_OBJECT,
|
listOf("Landroid/content/Context;", "L", "L", "L"),
|
||||||
Opcode.IPUT_OBJECT,
|
listOf(
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.NEW_INSTANCE,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
Opcode.IPUT_OBJECT,
|
||||||
Opcode.CONST,
|
Opcode.CONST,
|
||||||
Opcode.CONST_4,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.CHECK_CAST
|
Opcode.IPUT_OBJECT,
|
||||||
)
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.NEW_INSTANCE,
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
),
|
||||||
)
|
)
|
|
@ -1,26 +1,39 @@
|
||||||
package app.revanced.patches.music.layout.minimizedplayback
|
package app.revanced.patches.music.layout.minimizedplayback
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.music.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
import app.revanced.patches.music.layout.minimizedplayback.fingerprints.BackgroundPlaybackDisableFingerprint
|
||||||
|
import app.revanced.patches.music.layout.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Minimized playback music",
|
name = "Minimized playback",
|
||||||
description = "Enables minimized playback on Kids music.",
|
description = "Unlocks options for picture-in-picture and background playback.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object MinimizedPlaybackPatch : BytecodePatch(setOf(MinimizedPlaybackManagerFingerprint)) {
|
object MinimizedPlaybackPatch : BytecodePatch(
|
||||||
override fun execute(context: BytecodeContext) =
|
setOf(
|
||||||
MinimizedPlaybackManagerFingerprint.result?.mutableMethod?.addInstruction(
|
KidsMinimizedPlaybackPolicyControllerFingerprint,
|
||||||
|
BackgroundPlaybackDisableFingerprint,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
KidsMinimizedPlaybackPolicyControllerFingerprint.result?.mutableMethod?.addInstruction(
|
||||||
|
0,
|
||||||
|
"return-void",
|
||||||
|
) ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception
|
||||||
|
|
||||||
|
BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
return-void
|
const/4 v0, 0x1
|
||||||
"""
|
return v0
|
||||||
) ?: throw MinimizedPlaybackManagerFingerprint.exception
|
""",
|
||||||
|
) ?: throw BackgroundPlaybackDisableFingerprint.exception
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.music.layout.minimizedplayback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
|
||||||
|
"Z",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
listOf("L"),
|
||||||
|
listOf(
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.IGET,
|
||||||
|
Opcode.AND_INT_LIT16,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.IGET,
|
||||||
|
),
|
||||||
|
)
|
|
@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
|
internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint(
|
||||||
"V",
|
"V",
|
||||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
listOf("I", "L", "Z"),
|
listOf("I", "L", "Z"),
|
||||||
|
@ -22,5 +22,5 @@ internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
|
||||||
Opcode.CONST_4,
|
Opcode.CONST_4,
|
||||||
Opcode.IF_NE,
|
Opcode.IF_NE,
|
||||||
Opcode.IPUT_BOOLEAN,
|
Opcode.IPUT_BOOLEAN,
|
||||||
)
|
),
|
||||||
)
|
)
|
|
@ -2,41 +2,44 @@ package app.revanced.patches.music.layout.premium
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
|
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
|
||||||
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumParentFingerprint
|
import app.revanced.util.exception
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Hide get premium",
|
name = "Hide 'Get Music Premium' label",
|
||||||
description = "Removes all \"Get Premium\" evidences from the avatar menu.",
|
description = "Hides the red \"Get Music Premium\" label from the account menu.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object HideGetPremiumPatch : BytecodePatch(setOf(HideGetPremiumParentFingerprint)) {
|
object HideGetPremiumPatch : BytecodePatch(
|
||||||
|
setOf(HideGetPremiumFingerprint),
|
||||||
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val parentResult = HideGetPremiumParentFingerprint.result!!
|
HideGetPremiumFingerprint.result?.let {
|
||||||
HideGetPremiumFingerprint.resolve(context, parentResult.classDef)
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
val startIndex = parentResult.scanResult.patternScanResult!!.startIndex
|
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(insertIndex)
|
||||||
|
val getPremiumViewRegister = setVisibilityInstruction.registerC
|
||||||
|
val visibilityRegister = setVisibilityInstruction.registerD
|
||||||
|
|
||||||
val parentMethod = parentResult.mutableMethod
|
replaceInstruction(
|
||||||
parentMethod.replaceInstruction(
|
insertIndex,
|
||||||
startIndex,
|
"const/16 v$visibilityRegister, 0x8",
|
||||||
"""
|
)
|
||||||
const/4 v1, 0x0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
val result = HideGetPremiumFingerprint.result!!
|
addInstruction(
|
||||||
val method = result.mutableMethod
|
insertIndex + 1,
|
||||||
method.addInstruction(
|
"invoke-virtual {v$getPremiumViewRegister, v$visibilityRegister}, " +
|
||||||
startIndex,
|
"Landroid/view/View;->setVisibility(I)V",
|
||||||
"""
|
)
|
||||||
const/16 v0, 0x8
|
}
|
||||||
"""
|
} ?: throw HideGetPremiumFingerprint.exception
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object HideGetPremiumFingerprint : MethodFingerprint(
|
internal object HideGetPremiumFingerprint : MethodFingerprint(
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
"V",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
listOf(),
|
||||||
|
listOf(
|
||||||
Opcode.IF_NEZ,
|
Opcode.IF_NEZ,
|
||||||
Opcode.CONST_16,
|
Opcode.CONST_16,
|
||||||
Opcode.GOTO,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.NOP,
|
),
|
||||||
Opcode.INVOKE_VIRTUAL
|
listOf("FEmusic_history", "FEmusic_offline"),
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package app.revanced.patches.music.layout.premium.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object HideGetPremiumParentFingerprint : MethodFingerprint(
|
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
|
||||||
Opcode.IGET_BOOLEAN,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.INVOKE_STATIC
|
|
||||||
),
|
|
||||||
listOf("FEmusic_history"),
|
|
||||||
)
|
|
|
@ -1,71 +1,84 @@
|
||||||
package app.revanced.patches.music.layout.upgradebutton
|
package app.revanced.patches.music.layout.upgradebutton
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.extensions.newLabel
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.smali.toInstructions
|
import app.revanced.patcher.util.smali.toInstructions
|
||||||
import app.revanced.patches.music.layout.upgradebutton.fingerprints.PivotBarConstructorFingerprint
|
import app.revanced.patches.music.layout.upgradebutton.fingerprints.PivotBarConstructorFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
import app.revanced.util.getReference
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t
|
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Remove upgrade button",
|
name = "Remove upgrade button",
|
||||||
description = "Removes the upgrade tab from the pivot bar.",
|
description = "Removes the upgrade tab from the pivot bar.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object RemoveUpgradeButtonPatch : BytecodePatch(
|
object RemoveUpgradeButtonPatch : BytecodePatch(
|
||||||
setOf(PivotBarConstructorFingerprint)
|
setOf(PivotBarConstructorFingerprint),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val result = PivotBarConstructorFingerprint.result!!
|
PivotBarConstructorFingerprint.result?.let {
|
||||||
val implementation = result.mutableMethod.implementation!!
|
it.mutableMethod.apply {
|
||||||
|
val pivotBarElementFieldReference = getInstruction(it.scanResult.patternScanResult!!.endIndex - 1)
|
||||||
|
.getReference<FieldReference>()
|
||||||
|
|
||||||
val pivotBarElementFieldRef =
|
val register = (getInstructions().first() as Instruction35c).registerC
|
||||||
(implementation.instructions[result.scanResult.patternScanResult!!.endIndex - 1] as Instruction22c).reference
|
|
||||||
|
|
||||||
val register = (implementation.instructions.first() as Instruction35c).registerC
|
// First compile all the needed instructions.
|
||||||
// first compile all the needed instructions
|
val instructionList = """
|
||||||
val instructionList = """
|
invoke-interface { v0 }, Ljava/util/List;->size()I
|
||||||
invoke-interface { v0 }, Ljava/util/List;->size()I
|
move-result v1
|
||||||
move-result v1
|
const/4 v2, 0x4
|
||||||
const/4 v2, 0x4
|
invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object;
|
||||||
invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object;
|
iput-object v0, v$register, $pivotBarElementFieldReference
|
||||||
iput-object v0, v$register, $pivotBarElementFieldRef
|
""".toInstructions().toMutableList()
|
||||||
""".toInstructions().toMutableList()
|
|
||||||
|
|
||||||
|
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
val endIndex = result.scanResult.patternScanResult!!.endIndex
|
// Replace the instruction to retain the label at given index.
|
||||||
|
replaceInstruction(
|
||||||
|
endIndex - 1,
|
||||||
|
instructionList[0], // invoke-interface.
|
||||||
|
)
|
||||||
|
// Do not forget to remove this instruction since we added it already.
|
||||||
|
instructionList.removeFirst()
|
||||||
|
|
||||||
// replace the instruction to retain the label at given index
|
val exitInstruction = instructionList.last() // iput-object
|
||||||
implementation.replaceInstruction(
|
addInstruction(
|
||||||
endIndex - 1, instructionList[0] // invoke-interface
|
endIndex,
|
||||||
)
|
exitInstruction,
|
||||||
// do not forget to remove this instruction since we added it already
|
)
|
||||||
instructionList.removeFirst()
|
// Do not forget to remove this instruction since we added it already.
|
||||||
|
instructionList.removeLast()
|
||||||
|
|
||||||
val exitInstruction = instructionList.last() // iput-object
|
// Add the necessary if statement to remove the upgrade tab button in case it exists.
|
||||||
implementation.addInstruction(
|
instructionList.add(
|
||||||
endIndex, exitInstruction
|
2, // if-le.
|
||||||
)
|
BuilderInstruction22t(
|
||||||
// do not forget to remove this instruction since we added it already
|
Opcode.IF_LE,
|
||||||
instructionList.removeLast()
|
1,
|
||||||
|
2,
|
||||||
|
newLabel(endIndex),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
// add the necessary if statement to remove the upgrade tab button in case it exists
|
addInstructions(
|
||||||
instructionList.add(
|
endIndex,
|
||||||
2, // if-le
|
instructionList,
|
||||||
BuilderInstruction22t(
|
)
|
||||||
Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex)
|
}
|
||||||
)
|
} ?: throw PivotBarConstructorFingerprint.exception
|
||||||
)
|
|
||||||
|
|
||||||
implementation.addInstructions(
|
|
||||||
endIndex, instructionList
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +1,19 @@
|
||||||
package app.revanced.patches.music.layout.upgradebutton.fingerprints
|
package app.revanced.patches.music.layout.upgradebutton.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
|
||||||
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
|
|
||||||
internal object PivotBarConstructorFingerprint : MethodFingerprint(
|
internal object PivotBarConstructorFingerprint : MethodFingerprint(
|
||||||
"V",
|
"V",
|
||||||
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
listOf("L", "Z"),
|
listOf("L", "Z"),
|
||||||
listOf(
|
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.CHECK_CAST,
|
||||||
Opcode.INVOKE_INTERFACE,
|
Opcode.INVOKE_INTERFACE,
|
||||||
Opcode.GOTO,
|
Opcode.GOTO,
|
||||||
Opcode.NOP,
|
|
||||||
Opcode.IPUT_OBJECT,
|
Opcode.IPUT_OBJECT,
|
||||||
Opcode.RETURN_VOID
|
Opcode.RETURN_VOID,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,26 +1,12 @@
|
||||||
package app.revanced.patches.music.premium.backgroundplay
|
package app.revanced.patches.music.premium.backgroundplay
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patches.music.layout.minimizedplayback.MinimizedPlaybackPatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
@Deprecated("This patch has been merged into MinimizedPlaybackPatch.")
|
||||||
import app.revanced.patches.music.premium.backgroundplay.fingerprints.BackgroundPlaybackDisableFingerprint
|
object BackgroundPlayPatch : BytecodePatch(
|
||||||
|
dependencies = setOf(MinimizedPlaybackPatch::class),
|
||||||
|
) {
|
||||||
@Patch(
|
override fun execute(context: BytecodeContext) {
|
||||||
name = "Background play",
|
}
|
||||||
description = "Enables playing music in the background.",
|
}
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
|
||||||
)
|
|
||||||
@Suppress("unused")
|
|
||||||
object BackgroundPlayPatch : BytecodePatch(setOf(BackgroundPlaybackDisableFingerprint)) {
|
|
||||||
override fun execute(context: BytecodeContext) =
|
|
||||||
BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions(
|
|
||||||
0, """
|
|
||||||
const/4 v0, 0x1
|
|
||||||
return v0
|
|
||||||
"""
|
|
||||||
) ?: throw BackgroundPlaybackDisableFingerprint.exception
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package app.revanced.patches.music.premium.backgroundplay.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
|
|
||||||
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
|
|
||||||
internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
|
|
||||||
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf(
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET,
|
|
||||||
Opcode.AND_INT_LIT16,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.IF_NEZ,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.IGET,
|
|
||||||
Opcode.CONST,
|
|
||||||
Opcode.IF_NE,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.IF_NEZ,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.IGET,
|
|
||||||
Opcode.IF_NE,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.CHECK_CAST,
|
|
||||||
Opcode.GOTO,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.GOTO,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET_BOOLEAN,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.CONST_4,
|
|
||||||
Opcode.RETURN,
|
|
||||||
Opcode.RETURN,
|
|
||||||
Opcode.RETURN
|
|
||||||
)
|
|
||||||
)
|
|
Loading…
Reference in a new issue