fix(YouTube Music - Custom header): Not working on YouTube Music 7.25.53 https://github.com/inotia00/ReVanced_Extended/issues/2612

This commit is contained in:
inotia00 2024-12-31 20:43:57 +09:00
parent 87a6aec1dc
commit 8d045bc618
4 changed files with 76 additions and 22 deletions

View File

@ -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)
}
}
}

View File

@ -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)
)

View File

@ -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",
]
}
}

View File

@ -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