fix(YouTube Music/Enable zen mode): apply fingerprints compatible with the wider version

This commit is contained in:
inotia00 2024-03-20 02:33:42 +09:00
parent 73b52411f8
commit e3a1a8a0fe
5 changed files with 84 additions and 36 deletions

View File

@ -1,26 +1,31 @@
package app.revanced.patches.music.player.zenmode package app.revanced.patches.music.player.zenmode
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
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.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.player.zenmode.fingerprints.ZenModeFingerprint import app.revanced.patches.music.player.zenmode.fingerprints.ZenModeFingerprint
import app.revanced.patches.music.utils.fingerprints.PlayerColorFingerprint import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint
import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint
import app.revanced.patches.music.utils.integrations.Constants.PLAYER import app.revanced.patches.music.utils.integrations.Constants.PLAYER
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Patch( @Patch(
name = "Enable zen mode", name = "Enable zen mode",
description = "Adds an option to change the player background to light grey to reduce eye strain. Deprecated on YT Music 6.34.51+.", description = "Adds an option to change the player background to light grey to reduce eye strain.",
dependencies = [SettingsPatch::class], dependencies = [
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.apps.youtube.music", "com.google.android.apps.youtube.music",
@ -37,48 +42,55 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"6.33.52" "6.33.52"
] ]
) )
], ]
use = false
) )
@Suppress("unused") @Suppress("unused")
object ZenModePatch : BytecodePatch( object ZenModePatch : BytecodePatch(
setOf(PlayerColorFingerprint) setOf(MiniPlayerConstructorFingerprint)
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
PlayerColorFingerprint.result?.let { parentResult -> MiniPlayerConstructorFingerprint.result?.let { parentResult ->
ZenModeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { // Resolves fingerprints
SwitchToggleColorFingerprint.resolve(context, parentResult.classDef)
ZenModeFingerprint.resolve(context, parentResult.classDef)
// This method is used for old player background
// Deprecated since YT Music v6.34.51
ZenModeFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex val startIndex = it.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
val firstRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
val secondRegister =
getInstruction<OneRegisterInstruction>(startIndex + 2).registerA
val dummyRegister = secondRegister + 1
val replaceReferenceIndex = it.scanResult.patternScanResult!!.endIndex + 1 addInstructions(
val replaceReference =
getInstruction<ReferenceInstruction>(replaceReferenceIndex).reference
val insertIndex = replaceReferenceIndex + 1
addInstructionsWithLabels(
insertIndex, """ insertIndex, """
invoke-static {}, $PLAYER->enableZenMode()Z invoke-static {v$targetRegister}, $PLAYER->enableZenMode(I)I
move-result v$dummyRegister move-result v$targetRegister
if-eqz v$dummyRegister, :off
const v$dummyRegister, -0xfcfcfd
if-ne v$firstRegister, v$dummyRegister, :off
const v$firstRegister, -0xbfbfc0
const v$secondRegister, -0xbfbfc0
:off
sget-object v0, $replaceReference
""" """
) )
removeInstruction(replaceReferenceIndex)
} }
} ?: throw ZenModeFingerprint.exception }
} ?: throw PatchException("This version is not supported. Please use YT Music 6.33.52 or earlier.")
SwitchToggleColorFingerprint.result?.let {
val invokeDirectIndex = it.mutableMethod.getTargetIndex(0, Opcode.INVOKE_DIRECT)
val targetMethod = context.toMethodWalker(it.method)
.nextMethod(invokeDirectIndex, true)
.getMethod() as MutableMethod
targetMethod.apply {
addInstructions(
0, """
invoke-static {p1}, $PLAYER->enableZenMode(I)I
move-result p1
invoke-static {p2}, $PLAYER->enableZenMode(I)I
move-result p2
"""
)
}
} ?: throw SwitchToggleColorFingerprint.exception
} ?: throw MiniPlayerConstructorFingerprint.exception
SettingsPatch.addMusicPreference( SettingsPatch.addMusicPreference(
CategoryType.PLAYER, CategoryType.PLAYER,

View File

@ -14,6 +14,7 @@ object ZenModeFingerprint : MethodFingerprint(
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.GOTO, Opcode.GOTO,
Opcode.NOP Opcode.NOP,
Opcode.SGET_OBJECT
) )
) )

View File

@ -0,0 +1,15 @@
package app.revanced.patches.music.utils.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
import app.revanced.util.containsWideLiteralInstructionIndex
object MiniPlayerConstructorFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf("sharedToggleMenuItemMutations"),
customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(ColorGrey)
&& methodDef.containsWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
}
)

View File

@ -0,0 +1,18 @@
package app.revanced.patches.music.utils.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
object SwitchToggleColorFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
parameters = listOf("L", "J"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IGET
)
)

View File

@ -29,6 +29,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var LikeDislikeContainer: Long = -1 var LikeDislikeContainer: Long = -1
var MenuEntry: Long = -1 var MenuEntry: Long = -1
var MiniPlayerMdxPlaying: Long = -1 var MiniPlayerMdxPlaying: Long = -1
var MiniPlayerPlayPauseReplayButton: Long = -1
var MusicMenuLikeButtons: Long = -1 var MusicMenuLikeButtons: Long = -1
var MusicNotifierShelf: Long = -1 var MusicNotifierShelf: Long = -1
var MusicTastebuilderShelf: Long = -1 var MusicTastebuilderShelf: Long = -1
@ -65,6 +66,7 @@ object SharedResourceIdPatch : ResourcePatch() {
LikeDislikeContainer = find(ID, "like_dislike_container") LikeDislikeContainer = find(ID, "like_dislike_container")
MenuEntry = find(LAYOUT, "menu_entry") MenuEntry = find(LAYOUT, "menu_entry")
MiniPlayerMdxPlaying = find(STRING, "mini_player_mdx_playing") MiniPlayerMdxPlaying = find(STRING, "mini_player_mdx_playing")
MiniPlayerPlayPauseReplayButton = find(ID, "mini_player_play_pause_replay_button")
MusicMenuLikeButtons = find(LAYOUT, "music_menu_like_buttons") MusicMenuLikeButtons = find(LAYOUT, "music_menu_like_buttons")
MusicNotifierShelf = find(LAYOUT, "music_notifier_shelf") MusicNotifierShelf = find(LAYOUT, "music_notifier_shelf")
MusicTastebuilderShelf = find(LAYOUT, "music_tastebuilder_shelf") MusicTastebuilderShelf = find(LAYOUT, "music_tastebuilder_shelf")