diff --git a/src/main/kotlin/app/revanced/patches/music/layout/branding/icon/CustomBrandingIconPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/branding/icon/CustomBrandingIconPatch.kt index b73944091..0ba574ee7 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/branding/icon/CustomBrandingIconPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/branding/icon/CustomBrandingIconPatch.kt @@ -198,10 +198,15 @@ object CustomBrandingIconPatch : BaseResourcePatch( // Change splash icon. if (ChangeSplashIcon == true) { - splashIconResourceGroups.let { resourceGroups -> - resourceGroups.forEach { - context.copyResources("$appIconResourcePath/splash", it) + // Some resources have been removed in the latest YouTube Music. + // For compatibility, use try...catch. + try { + splashIconResourceGroups.let { resourceGroups -> + resourceGroups.forEach { + context.copyResources("$appIconResourcePath/splash", it) + } } + } catch (_: Exception) { } } diff --git a/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt index 37190159f..5c60085e3 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt @@ -20,7 +20,7 @@ import app.revanced.util.literalInstructionBooleanHook "com.google.android.apps.youtube.music", [ "7.08.54", - "7.13.52", + "7.16.52", ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index 151854766..8bc50eed1 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -34,6 +34,8 @@ import app.revanced.patches.music.player.components.fingerprints.QuickSeekOverla import app.revanced.patches.music.player.components.fingerprints.RemixGenericButtonFingerprint import app.revanced.patches.music.player.components.fingerprints.RepeatTrackFingerprint import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint +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.player.components.fingerprints.SwipeToCloseFingerprint import app.revanced.patches.music.player.components.fingerprints.SwitchToggleColorFingerprint import app.revanced.patches.music.player.components.fingerprints.ZenModeFingerprint @@ -740,28 +742,53 @@ object PlayerComponentsPatch : BaseBytecodePatch( it.mutableMethod.apply { rememberShuffleStateObjectClass = definingClass - val startIndex = it.scanResult.patternScanResult!!.startIndex - val endIndex = it.scanResult.patternScanResult!!.endIndex - val imageViewIndex = - getTargetIndexWithFieldReferenceTypeOrThrow("Landroid/widget/ImageView;") + val constIndex = getWideLiteralInstructionIndex(45468) + val iGetObjectIndex = getTargetIndexOrThrow(constIndex, Opcode.IGET_OBJECT) + val checkCastIndex = getTargetIndexOrThrow(iGetObjectIndex, Opcode.CHECK_CAST) + + val ordinalIndex = indexOfOrdinalInstruction(this) + val imageViewIndex = indexOfImageViewInstruction(this) + + val iGetObjectReference = + getInstruction(iGetObjectIndex).reference + val invokeInterfaceReference = + getInstruction(iGetObjectIndex + 1).reference + val checkCastReference = + getInstruction(checkCastIndex).reference + val getOrdinalClassReference = + getInstruction(checkCastIndex + 1).reference + val ordinalReference = + getInstruction(ordinalIndex).reference - val shuffleReference1 = getInstruction(startIndex).reference - val shuffleReference2 = - getInstruction(startIndex + 1).reference - val shuffleReference3 = getInstruction(endIndex).reference - val shuffleFieldReference = shuffleReference3 as FieldReference rememberShuffleStateImageViewReference = getInstruction(imageViewIndex).reference rememberShuffleStateShuffleStateLabel = """ - iget-object v1, v0, $shuffleReference1 - invoke-interface {v1}, $shuffleReference2 + iget-object v1, v0, $iGetObjectReference + invoke-interface {v1}, $invokeInterfaceReference move-result-object v1 - check-cast v1, ${shuffleFieldReference.definingClass} - iget-object v1, v1, $shuffleReference3 - invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I - move-result v1 + check-cast v1, $checkCastReference + """ + + rememberShuffleStateShuffleStateLabel += if (getInstruction(checkCastIndex + 1).opcode == Opcode.INVOKE_VIRTUAL) { + // YouTube Music 7.16.52+ """ + invoke-virtual {v1}, $getOrdinalClassReference + move-result-object v1 + + """.trimIndent() + } else { + """ + iget-object v1, v1, $getOrdinalClassReference + + """.trimIndent() + } + + rememberShuffleStateShuffleStateLabel += """ + invoke-virtual {v1}, $ordinalReference + move-result v1 + + """.trimIndent() } val constructorMethod = @@ -770,7 +797,7 @@ object PlayerComponentsPatch : BaseBytecodePatch( constructorMethod.apply { addInstruction( - implementation!!.instructions.size - 1, + implementation!!.instructions.lastIndex, "sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass" ) } @@ -836,9 +863,10 @@ object PlayerComponentsPatch : BaseBytecodePatch( sget-object v0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass """ + rememberShuffleStateShuffleStateLabel + """ iget-object v3, v0, $rememberShuffleStateImageViewReference - invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z + if-eqz v3, :dont_shuffle + invoke-virtual {v3}, Landroid/view/View;->callOnClick()Z if-eqz v1, :dont_shuffle - invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z + invoke-virtual {v3}, Landroid/view/View;->callOnClick()Z :dont_shuffle return-void """ diff --git a/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt index 058bb631d..64f792f24 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt @@ -2,20 +2,38 @@ package app.revanced.patches.music.player.components.fingerprints 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.util.containsWideLiteralInstructionIndex +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.Method +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal object ShuffleClassReferenceFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET_OBJECT - ), - strings = listOf("Unknown shuffle mode") -) + strings = listOf("Unknown shuffle mode"), + customFingerprint = { methodDef, _ -> + methodDef.containsWideLiteralInstructionIndex(45468) && + indexOfOrdinalInstruction(methodDef) >= 0 && + indexOfImageViewInstruction(methodDef) >= 0 + } +) { + fun indexOfOrdinalInstruction(methodDef: Method) = + methodDef.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "ordinal" + } + + fun indexOfImageViewInstruction(methodDef: Method) = + methodDef.indexOfFirstInstruction { + opcode == Opcode.IGET_OBJECT && + getReference()?.type == "Landroid/widget/ImageView;" + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt b/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt index aa452910a..6405d96e1 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt @@ -11,8 +11,8 @@ object Constants { "6.33.52", // This is the latest version with the legacy code of YouTube Music. "6.42.55", // This is the latest version that supports Android 7.0 "6.51.53", // This is the latest version of YouTube Music 6.xx.xx - "7.12.52", // This was the latest version that was supported by the previous patch. - "7.13.52", // This is the latest version supported by the RVX patch. + "7.15.52", // This was the latest version that was supported by the previous patch. + "7.16.52", // This is the latest version supported by the RVX patch. ) ) )