chore(YouTube Music): replace with a fingerprint that supports a wider range of versions

This commit is contained in:
inotia00
2024-09-17 20:35:17 +09:00
parent afd19dead4
commit e5abab21a0
7 changed files with 175 additions and 22 deletions

View File

@ -13,6 +13,8 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.player.components.fingerprints.AudioVideoSwitchToggleFingerprint
import app.revanced.patches.music.player.components.fingerprints.EngagementPanelHeightFingerprint
import app.revanced.patches.music.player.components.fingerprints.EngagementPanelHeightParentFingerprint
import app.revanced.patches.music.player.components.fingerprints.HandleSearchRenderedFingerprint
import app.revanced.patches.music.player.components.fingerprints.HandleSignInEventFingerprint
import app.revanced.patches.music.player.components.fingerprints.InteractionLoggingEnumFingerprint
@ -59,6 +61,7 @@ import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.alsoResolve
import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
@ -102,6 +105,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
AudioVideoSwitchToggleFingerprint,
EngagementPanelHeightParentFingerprint,
HandleSearchRenderedFingerprint,
InteractionLoggingEnumFingerprint,
MinimizedPlayerFingerprint,
@ -530,15 +534,12 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method ->
method.parameters == listOf("Landroid/view/View;", "I")
}?.apply {
val bottomSheetBehaviorIndex =
implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.INVOKE_VIRTUAL
&& instruction.getReference<MethodReference>()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
&& instruction.getReference<MethodReference>()?.parameterTypes?.first() == "Z"
val bottomSheetBehaviorIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL
&& reference?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
&& reference.parameterTypes.first() == "Z"
}
if (bottomSheetBehaviorIndex < 0)
throw PatchException("Could not find bottomSheetBehaviorIndex")
val freeRegister =
getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
@ -744,18 +745,20 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.mutableMethod.apply {
rememberShuffleStateObjectClass = definingClass
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45468)
val iGetObjectIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IGET_OBJECT)
val checkCastIndex =
indexOfFirstInstructionOrThrow(iGetObjectIndex, Opcode.CHECK_CAST)
val ordinalIndex = indexOfOrdinalInstruction(this)
val imageViewIndex = indexOfImageViewInstruction(this)
val ordinalIndex = indexOfOrdinalInstruction(this)
val invokeInterfaceIndex =
indexOfFirstInstructionReversedOrThrow(ordinalIndex, Opcode.INVOKE_INTERFACE)
val iGetObjectIndex =
indexOfFirstInstructionReversedOrThrow(invokeInterfaceIndex, Opcode.IGET_OBJECT)
val checkCastIndex =
indexOfFirstInstructionOrThrow(invokeInterfaceIndex, Opcode.CHECK_CAST)
val iGetObjectReference =
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
val invokeInterfaceReference =
getInstruction<ReferenceInstruction>(iGetObjectIndex + 1).reference
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
val checkCastReference =
getInstruction<ReferenceInstruction>(checkCastIndex).reference
val getOrdinalClassReference =
@ -890,12 +893,82 @@ object PlayerComponentsPatch : BaseBytecodePatch(
// region patch for restore old comments popup panels
OldEngagementPanelFingerprint.result?.let {
var restoreOldCommentsPopupPanel = false
if (SettingsPatch.upward0627 && !SettingsPatch.upward0718) {
OldEngagementPanelFingerprint.injectLiteralInstructionBooleanCall(
45427672,
"$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z"
)
restoreOldCommentsPopupPanel = true
} else if (SettingsPatch.upward0718) {
// region disable player from being pushed to the top when opening a comment
MppWatchWhileLayoutFingerprint.resultOrThrow().mutableMethod.apply {
val callableIndex =
MppWatchWhileLayoutFingerprint.indexOfCallableInstruction(this)
val insertIndex = indexOfFirstInstructionReversedOrThrow(callableIndex, Opcode.NEW_INSTANCE)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructionsWithLabels(
insertIndex, """
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels()Z
move-result v$insertRegister
if-eqz v$insertRegister, :restore
""", ExternalLabel("restore", getInstruction(callableIndex + 1))
)
}
// endregion
// region region limit the height of the engagement panel
EngagementPanelHeightFingerprint.alsoResolve(
context, EngagementPanelHeightParentFingerprint
).let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z
move-result v$targetRegister
"""
)
}
}
MiniPlayerDefaultViewVisibilityFingerprint.resultOrThrow().let {
it.mutableClass.methods.find { method ->
method.parameters == listOf("Landroid/view/View;", "I")
}?.apply {
val targetIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_INTERFACE
&& reference?.returnType == "Z"
&& reference.parameterTypes.size == 0
} + 1
val targetRegister =
getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z
move-result v$targetRegister
"""
)
} ?: throw PatchException("Could not find targetMethod")
}
// endregion
restoreOldCommentsPopupPanel = true
}
if (restoreOldCommentsPopupPanel) {
SettingsPatch.addSwitchPreference(
CategoryType.PLAYER,
"revanced_restore_old_comments_popup_panels",

View File

@ -0,0 +1,26 @@
package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object EngagementPanelHeightFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
),
parameters = emptyList(),
customFingerprint = custom@{ methodDef, _ ->
methodDef.indexOfFirstInstruction {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "booleanValue"
} >= 0
}
)

View File

@ -0,0 +1,28 @@
package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
internal object EngagementPanelHeightParentFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(Opcode.NEW_ARRAY),
parameters = emptyList(),
customFingerprint = custom@{ methodDef, _ ->
if (methodDef.definingClass.startsWith("Lcom/")) {
return@custom false
}
if (methodDef.returnType == "Ljava/lang/Object;") {
return@custom false
}
methodDef.indexOfFirstInstruction {
opcode == Opcode.CHECK_CAST &&
(this as? ReferenceInstruction)?.reference?.toString() == "Lcom/google/android/libraries/youtube/engagementpanel/size/EngagementPanelSizeBehavior;"
} >= 0
}
)

View File

@ -1,16 +1,36 @@
package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.player.components.fingerprints.MppWatchWhileLayoutFingerprint.indexOfCallableInstruction
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object MppWatchWhileLayoutFingerprint : MethodFingerprint(
returnType = "V",
opcodes = listOf(Opcode.NEW_ARRAY),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/MppWatchWhileLayout;")
&& methodDef.name == "onFinishInflate"
&& methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton)
customFingerprint = custom@{ methodDef, _ ->
if (!methodDef.definingClass.endsWith("/MppWatchWhileLayout;")) {
return@custom false
}
if (methodDef.name != "onFinishInflate") {
return@custom false
}
methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton) &&
indexOfCallableInstruction(methodDef) >= 0
}
)
) {
fun indexOfCallableInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.returnType == "V" &&
reference.parameterTypes.size == 1 &&
reference.parameterTypes.firstOrNull() == "Ljava/util/concurrent/Callable;"
}
}

View File

@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfImageViewInstruction
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfOrdinalInstruction
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.YtFillArrowShuffle
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
@ -19,7 +20,7 @@ internal object ShuffleClassReferenceFingerprint : MethodFingerprint(
parameters = emptyList(),
strings = listOf("Unknown shuffle mode"),
customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionValue(45468) &&
methodDef.containsWideLiteralInstructionValue(YtFillArrowShuffle) &&
indexOfOrdinalInstruction(methodDef) >= 0 &&
indexOfImageViewInstruction(methodDef) >= 0
}

View File

@ -7,6 +7,7 @@ import app.revanced.patches.shared.mapping.ResourceMappingPatch
import app.revanced.patches.shared.mapping.ResourceMappingPatch.getId
import app.revanced.patches.shared.mapping.ResourceType.BOOL
import app.revanced.patches.shared.mapping.ResourceType.COLOR
import app.revanced.patches.shared.mapping.ResourceType.DRAWABLE
import app.revanced.patches.shared.mapping.ResourceType.DIMEN
import app.revanced.patches.shared.mapping.ResourceType.ID
import app.revanced.patches.shared.mapping.ResourceType.LAYOUT
@ -57,6 +58,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var TouchOutside = -1L
var TrimSilenceSwitch: Long = -1
var VarispeedUnavailableTitle = -1L
var YtFillArrowShuffle = -1L
override fun execute(context: ResourceContext) {
@ -102,6 +104,7 @@ object SharedResourceIdPatch : ResourcePatch() {
TouchOutside = getId(ID, "touch_outside")
TrimSilenceSwitch = getId(ID, "trim_silence_switch")
VarispeedUnavailableTitle = getId(STRING, "varispeed_unavailable_title")
YtFillArrowShuffle = getId(DRAWABLE, "yt_fill_arrow_shuffle_vd_theme_24")
}
}

View File

@ -132,8 +132,10 @@ object SettingsPatch : BaseResourcePatch(
val playServicesVersion = node.textContent.toInt()
upward0627 = 234412000 <= playServicesVersion
upward0636 = 240399000 <= playServicesVersion
upward0642 = 240999000 <= playServicesVersion
upward0718 = 243699000 <= playServicesVersion
break
}