diff --git a/patches/api/patches.api b/patches/api/patches.api index 543bd5f9d..5416c799e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -568,7 +568,9 @@ public final class app/revanced/patches/shared/misc/extension/ExtensionHook { } public final class app/revanced/patches/shared/misc/extension/SharedExtensionPatchKt { + public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static final fun extensionHook (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; + public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lapp/revanced/patcher/Fingerprint;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static synthetic fun extensionHook$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patches/shared/misc/extension/ExtensionHook; public static final fun sharedExtensionPatch (Ljava/lang/String;[Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; public static final fun sharedExtensionPatch ([Lapp/revanced/patches/shared/misc/extension/ExtensionHook;)Lapp/revanced/patcher/patch/BytecodePatch; diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt index 40ced06a0..4828fe48a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt @@ -41,11 +41,12 @@ fun sharedExtensionPatch( execute { if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) { - throw PatchException( - "Shared extension has not been merged yet. This patch can not succeed without merging it.", - ) + throw PatchException("Shared extension is not available. This patch can not succeed without it.") } + } + finalize { + // The hooks are made in finalize to ensure that the context is hooked before any other patches. hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) } // Modify Utils method to include the patches release version. @@ -109,8 +110,14 @@ class ExtensionHook internal constructor( } } +fun extensionHook( + insertIndexResolver: ((Method) -> Int) = { 0 }, + contextRegisterResolver: (Method) -> String = { "p0" }, + fingerprint: Fingerprint, +) = ExtensionHook(fingerprint, insertIndexResolver, contextRegisterResolver) + fun extensionHook( insertIndexResolver: ((Method) -> Int) = { 0 }, contextRegisterResolver: (Method) -> String = { "p0" }, fingerprintBuilderBlock: FingerprintBuilder.() -> Unit, -) = ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver) +) = extensionHook(insertIndexResolver, contextRegisterResolver, fingerprint(block = fingerprintBuilderBlock)) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt index 0e54bb691..64173c18c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt @@ -17,7 +17,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c -import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference import com.android.tools.smali.dexlib2.util.MethodUtil @@ -110,19 +109,18 @@ fun gmsCoreSupportPatch( // region Collection of transformations that are applied to all strings. - fun commonTransform(referencedString: String): String? = - when (referencedString) { - "com.google", - "com.google.android.gms", - in PERMISSIONS, - in ACTIONS, - in AUTHORITIES, - -> referencedString.replace("com.google", gmsCoreVendorGroupId!!) + fun commonTransform(referencedString: String): String? = when (referencedString) { + "com.google", + "com.google.android.gms", + in PERMISSIONS, + in ACTIONS, + in AUTHORITIES, + -> referencedString.replace("com.google", gmsCoreVendorGroupId!!) - // No vendor prefix for whatever reason... - "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds" - else -> null - } + // No vendor prefix for whatever reason... + "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds" + else -> null + } fun contentUrisTransform(str: String): String? { // only when content:// uri @@ -205,16 +203,8 @@ fun gmsCoreSupportPatch( // Verify GmsCore is installed and whitelisted for power optimizations and background usage. mainActivityOnCreateFingerprint.method.apply { - // Temporary fix for patches with an extension patch that hook the onCreate method as well. - val setContextIndex = indexOfFirstInstruction { - val reference = getReference() ?: return@indexOfFirstInstruction false - - reference.toString() == "Lapp/revanced/extension/shared/Utils;->setContext(Landroid/content/Context;)V" - } - - // Add after setContext call, because this patch needs the context. addInstructions( - if (setContextIndex < 0) 0 else setContextIndex + 1, + 0, "invoke-static/range { p0 .. p0 }, Lapp/revanced/extension/shared/GmsCoreSupport;->" + "checkGmsCore(Landroid/app/Activity;)V", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt index bb4e62a11..4c4889d97 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt @@ -7,6 +7,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.spotify.misc.check.checkEnvironmentPatch import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch import app.revanced.util.getReference @@ -30,7 +31,12 @@ val unlockPremiumPatch = bytecodePatch( ) { compatibleWith("com.spotify.music") - dependsOn(sharedExtensionPatch) + dependsOn( + sharedExtensionPatch, + // Currently there is no easy way to make a mandatory patch, + // so for now this is a dependent of this patch. + checkEnvironmentPatch, + ) execute { // Make _value accessible so that it can be overridden in the extension. diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt new file mode 100644 index 000000000..81d42ce66 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/check/CheckEnvironmentPatch.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.spotify.misc.check + +import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch +import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint +import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch + +internal val checkEnvironmentPatch = checkEnvironmentPatch( + mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint, + extensionPatch = sharedExtensionPatch, + "com.spotify.music", +) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt index 98afe65b2..438fe49df 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/ExtensionPatch.kt @@ -2,6 +2,7 @@ package app.revanced.patches.spotify.misc.extension import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.shared.misc.extension.sharedExtensionPatch +import app.revanced.patches.spotify.shared.SPOTIFY_MAIN_ACTIVITY_LEGACY /** * If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets, @@ -11,10 +12,10 @@ import app.revanced.patches.shared.misc.extension.sharedExtensionPatch internal var IS_SPOTIFY_LEGACY_APP_TARGET = false val sharedExtensionPatch = bytecodePatch { - dependsOn(sharedExtensionPatch("spotify", spotifyMainActivityOnCreate)) + dependsOn(sharedExtensionPatch("spotify", mainActivityOnCreateHook)) execute { - IS_SPOTIFY_LEGACY_APP_TARGET = spotifyMainActivityOnCreate.fingerprint + IS_SPOTIFY_LEGACY_APP_TARGET = mainActivityOnCreateHook.fingerprint .originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY } } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt index 956c5610e..6153f4b60 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt @@ -1,17 +1,6 @@ package app.revanced.patches.spotify.misc.extension import app.revanced.patches.shared.misc.extension.extensionHook +import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint -private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;" - -/** - * Main activity of target 8.6.98.900. - */ -internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;" - -internal val spotifyMainActivityOnCreate = extensionHook { - custom { method, classDef -> - method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY - || classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY) - } -} +internal val mainActivityOnCreateHook = extensionHook(fingerprint = mainActivityOnCreateFingerprint) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt new file mode 100644 index 000000000..14149ac7a --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/shared/Fingerprints.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.spotify.shared + +import app.revanced.patcher.fingerprint + +private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;" + +/** + * Main activity of target 8.6.98.900. + */ +internal const val SPOTIFY_MAIN_ACTIVITY_LEGACY = "Lcom/spotify/music/MainActivity;" + +internal val mainActivityOnCreateFingerprint = fingerprint { + custom { method, classDef -> + method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY + || classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY) + } +} \ No newline at end of file