diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt index db08f642f..8143cfddd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt @@ -5,6 +5,13 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.patch.PatchList.CUSTOM_HEADER_FOR_YOUTUBE_MUSIC +import app.revanced.patches.music.utils.playservice.is_7_06_or_greater +import app.revanced.patches.music.utils.playservice.versionCheckPatch +import app.revanced.patches.music.utils.resourceid.actionBarLogo +import app.revanced.patches.music.utils.resourceid.actionBarLogoRingo2 +import app.revanced.patches.music.utils.resourceid.sharedResourceIdPatch +import app.revanced.patches.music.utils.resourceid.ytmLogo +import app.revanced.patches.music.utils.resourceid.ytmLogoRingo2 import app.revanced.patches.music.utils.settings.ResourceUtils.getIconType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.settingsPatch @@ -13,8 +20,7 @@ import app.revanced.util.Utils.printWarn import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.copyFile import app.revanced.util.copyResources -import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall -import app.revanced.util.fingerprint.resolvable +import app.revanced.util.replaceLiteralInstructionCall import app.revanced.util.underBarOrThrow import app.revanced.util.valueOrThrow @@ -100,24 +106,31 @@ private val getDescription = { private val changeHeaderBytecodePatch = bytecodePatch( description = "changeHeaderBytecodePatch" ) { + dependsOn( + sharedResourceIdPatch, + versionCheckPatch, + ) + execute { + /** * New Header has been added from YouTube Music v7.04.51. * - * The new header's file names are 'action_bar_logo_ringo2.png' and 'ytm_logo_ringo2.png'. + * The new header's file names are 'action_bar_logo_ringo2.png' and 'ytm_logo_ringo2.png'. * The only difference between the existing header and the new header is the dimensions of the image. * * The affected patch is [changeHeaderPatch]. - * - * TODO: Add a new header image file to [changeHeaderPatch] later. */ - if (!headerSwitchConfigFingerprint.resolvable()) { + if (!is_7_06_or_greater) { return@execute } - headerSwitchConfigFingerprint.injectLiteralInstructionBooleanCall( - 45617851L, - "0x0" - ) + + listOf( + actionBarLogoRingo2 to actionBarLogo, + ytmLogoRingo2 to ytmLogo, + ).forEach { (originalResource, replacementResource) -> + replaceLiteralInstructionCall(originalResource, replacementResource) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/Fingerprints.kt deleted file mode 100644 index 866303d2f..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/Fingerprints.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.music.layout.header - -import app.revanced.util.fingerprint.legacyFingerprint -import app.revanced.util.or -import com.android.tools.smali.dexlib2.AccessFlags - -internal val headerSwitchConfigFingerprint = legacyFingerprint( - name = "headerSwitchConfigFingerprint", - returnType = "Z", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - literals = listOf(45617851L) -) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index a3358901f..94d001193 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.shared.mapping.ResourceType.BOOL import app.revanced.patches.shared.mapping.ResourceType.COLOR import app.revanced.patches.shared.mapping.ResourceType.DIMEN +import app.revanced.patches.shared.mapping.ResourceType.DRAWABLE import app.revanced.patches.shared.mapping.ResourceType.ID import app.revanced.patches.shared.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.mapping.ResourceType.STRING @@ -14,6 +15,10 @@ import app.revanced.patches.shared.mapping.resourceMappings var accountSwitcherAccessibility = -1L private set +var actionBarLogo = -1L + private set +var actionBarLogoRingo2 = -1L + private set var bottomSheetRecyclerView = -1L private set var buttonContainer = -1L @@ -94,6 +99,10 @@ var trimSilenceSwitch = -1L private set var varispeedUnavailableTitle = -1L private set +var ytmLogo = -1L + private set +var ytmLogoRingo2 = -1L + private set internal val sharedResourceIdPatch = resourcePatch( description = "sharedResourceIdPatch" @@ -105,6 +114,14 @@ internal val sharedResourceIdPatch = resourcePatch( STRING, "account_switcher_accessibility_label", ] + actionBarLogo = resourceMappings[ + DRAWABLE, + "action_bar_logo", + ] + actionBarLogoRingo2 = resourceMappings[ + DRAWABLE, + "action_bar_logo_ringo2", + ] bottomSheetRecyclerView = resourceMappings[ LAYOUT, "bottom_sheet_recycler_view" @@ -265,5 +282,13 @@ internal val sharedResourceIdPatch = resourcePatch( STRING, "varispeed_unavailable_title" ] + ytmLogo = resourceMappings[ + DRAWABLE, + "ytm_logo", + ] + ytmLogoRingo2 = resourceMappings[ + DRAWABLE, + "ytm_logo_ringo2", + ] } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 9f9c0989d..cd58c6e34 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -263,6 +263,34 @@ fun MutableMethod.injectLiteralInstructionViewCall( ) } +fun BytecodePatchContext.replaceLiteralInstructionCall( + originalLiteral: Long, + replaceLiteral: Long +) { + classes.forEach { classDef -> + classDef.methods.forEach { method -> + method.implementation.apply { + this?.instructions?.forEachIndexed { _, instruction -> + if (instruction.opcode != Opcode.CONST) + return@forEachIndexed + if ((instruction as Instruction31i).wideLiteral != originalLiteral) + return@forEachIndexed + + proxy(classDef) + .mutableClass + .findMutableMethodOf(method).apply { + val index = indexOfFirstLiteralInstructionOrThrow(originalLiteral) + val register = + (instruction as OneRegisterInstruction).registerA + + replaceInstruction(index, "const v$register, $replaceLiteral") + } + } + } + } + } +} + fun BytecodePatchContext.replaceLiteralInstructionCall( literal: Long, smaliInstruction: String