diff --git a/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt b/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt index e37d8c928..5d657cf3c 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt @@ -1,26 +1,31 @@ package app.revanced.patches.music.player.zenmode 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.removeInstruction 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.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod 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.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch 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.ReferenceInstruction @Patch( 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+.", - dependencies = [SettingsPatch::class], + description = "Adds an option to change the player background to light grey to reduce eye strain.", + dependencies = [ + SettingsPatch::class, + SharedResourceIdPatch::class + ], compatiblePackages = [ CompatiblePackage( "com.google.android.apps.youtube.music", @@ -37,48 +42,55 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction "6.33.52" ] ) - ], - use = false + ] ) @Suppress("unused") object ZenModePatch : BytecodePatch( - setOf(PlayerColorFingerprint) + setOf(MiniPlayerConstructorFingerprint) ) { override fun execute(context: BytecodeContext) { - PlayerColorFingerprint.result?.let { parentResult -> - ZenModeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { + MiniPlayerConstructorFingerprint.result?.let { parentResult -> + // 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 { val startIndex = it.scanResult.patternScanResult!!.startIndex + val targetRegister = getInstruction(startIndex).registerA - val firstRegister = getInstruction(startIndex).registerA - val secondRegister = - getInstruction(startIndex + 2).registerA - val dummyRegister = secondRegister + 1 + val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1 - val replaceReferenceIndex = it.scanResult.patternScanResult!!.endIndex + 1 - val replaceReference = - getInstruction(replaceReferenceIndex).reference - - val insertIndex = replaceReferenceIndex + 1 - - addInstructionsWithLabels( + addInstructions( insertIndex, """ - invoke-static {}, $PLAYER->enableZenMode()Z - move-result v$dummyRegister - 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 + invoke-static {v$targetRegister}, $PLAYER->enableZenMode(I)I + move-result v$targetRegister """ ) - 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( CategoryType.PLAYER, diff --git a/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt index 619f7acc9..8dadbed7d 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt @@ -14,6 +14,7 @@ object ZenModeFingerprint : MethodFingerprint( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.GOTO, - Opcode.NOP + Opcode.NOP, + Opcode.SGET_OBJECT ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt new file mode 100644 index 000000000..00c9a819f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt @@ -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) + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt new file mode 100644 index 000000000..e819795dd --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt @@ -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 + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index c9070e6aa..7bb08f691 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -29,6 +29,7 @@ object SharedResourceIdPatch : ResourcePatch() { var LikeDislikeContainer: Long = -1 var MenuEntry: Long = -1 var MiniPlayerMdxPlaying: Long = -1 + var MiniPlayerPlayPauseReplayButton: Long = -1 var MusicMenuLikeButtons: Long = -1 var MusicNotifierShelf: Long = -1 var MusicTastebuilderShelf: Long = -1 @@ -65,6 +66,7 @@ object SharedResourceIdPatch : ResourcePatch() { LikeDislikeContainer = find(ID, "like_dislike_container") MenuEntry = find(LAYOUT, "menu_entry") MiniPlayerMdxPlaying = find(STRING, "mini_player_mdx_playing") + MiniPlayerPlayPauseReplayButton = find(ID, "mini_player_play_pause_replay_button") MusicMenuLikeButtons = find(LAYOUT, "music_menu_like_buttons") MusicNotifierShelf = find(LAYOUT, "music_notifier_shelf") MusicTastebuilderShelf = find(LAYOUT, "music_tastebuilder_shelf")