Skip to content

Commit

Permalink
chore(YouTube Music): replace with a fingerprint that supports a wide…
Browse files Browse the repository at this point in the history
…r range of versions
  • Loading branch information
inotia00 committed Sep 17, 2024
1 parent afd19de commit e5abab2
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -102,6 +105,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
AudioVideoSwitchToggleFingerprint,
EngagementPanelHeightParentFingerprint,
HandleSearchRenderedFingerprint,
InteractionLoggingEnumFingerprint,
MinimizedPlayerFingerprint,
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
)
Original file line number Diff line number Diff line change
@@ -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
}
)
Original file line number Diff line number Diff line change
@@ -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;"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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")

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit e5abab2

Please sign in to comment.