From 5c5a1e4b8be5acc2e787873b48b735a0501e232c Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 26 Mar 2025 04:24:47 +0100 Subject: [PATCH] feat(Spotify): Add `Unlock premium` patch (#4644) Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Co-authored-by: Brosssh --- extensions/spotify/build.gradle.kts | 3 ++ .../spotify/src/main/AndroidManifest.xml | 1 + extensions/spotify/stub/build.gradle.kts | 17 +++++++ .../spotify/stub/src/main/AndroidManifest.xml | 1 + .../internal/AccountAttribute.java | 5 +++ patches/api/patches.api | 4 ++ .../patches/spotify/misc/Fingerprints.kt | 18 ++++++++ .../patches/spotify/navbar/Fingerprints.kt | 11 ----- .../spotify/navbar/PremiumNavbarTabPatch.kt | 44 ++----------------- 9 files changed, 52 insertions(+), 52 deletions(-) create mode 100644 extensions/spotify/build.gradle.kts create mode 100644 extensions/spotify/src/main/AndroidManifest.xml create mode 100644 extensions/spotify/stub/build.gradle.kts create mode 100644 extensions/spotify/stub/src/main/AndroidManifest.xml create mode 100644 extensions/spotify/stub/src/main/java/com/spotify/remoteconfig/internal/AccountAttribute.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt diff --git a/extensions/spotify/build.gradle.kts b/extensions/spotify/build.gradle.kts new file mode 100644 index 000000000..07cce9e23 --- /dev/null +++ b/extensions/spotify/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + compileOnly(project(":extensions:spotify:stub")) +} diff --git a/extensions/spotify/src/main/AndroidManifest.xml b/extensions/spotify/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9b65eb06c --- /dev/null +++ b/extensions/spotify/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/extensions/spotify/stub/build.gradle.kts b/extensions/spotify/stub/build.gradle.kts new file mode 100644 index 000000000..a8da923ed --- /dev/null +++ b/extensions/spotify/stub/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + id(libs.plugins.android.library.get().pluginId) +} + +android { + namespace = "app.revanced.extension" + compileSdk = 34 + + defaultConfig { + minSdk = 26 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} diff --git a/extensions/spotify/stub/src/main/AndroidManifest.xml b/extensions/spotify/stub/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9b65eb06c --- /dev/null +++ b/extensions/spotify/stub/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/extensions/spotify/stub/src/main/java/com/spotify/remoteconfig/internal/AccountAttribute.java b/extensions/spotify/stub/src/main/java/com/spotify/remoteconfig/internal/AccountAttribute.java new file mode 100644 index 000000000..5b6d0fa18 --- /dev/null +++ b/extensions/spotify/stub/src/main/java/com/spotify/remoteconfig/internal/AccountAttribute.java @@ -0,0 +1,5 @@ +package com.spotify.remoteconfig.internal; + +public final class AccountAttribute { + public Object value_; +} diff --git a/patches/api/patches.api b/patches/api/patches.api index 92106329f..f84f9113e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -816,6 +816,10 @@ public final class app/revanced/patches/spotify/lite/ondemand/OnDemandPatchKt { public static final fun getOnDemandPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/spotify/misc/UnlockPremiumPatchKt { + public static final fun getUnlockPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt { public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt new file mode 100644 index 000000000..1fe64b8cf --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/Fingerprints.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.spotify.misc + +import app.revanced.patcher.fingerprint + +internal val accountAttributeFingerprint = fingerprint { + custom { _, c -> c.endsWith("internal/AccountAttribute;") } +} + +internal val productStateProtoFingerprint = fingerprint { + returns("Ljava/util/Map;") + custom { _, classDef -> + classDef.endsWith("ProductStateProto;") + } +} + +internal val buildQueryParametersFingerprint = fingerprint { + strings("trackRows", "device_type:tablet") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt deleted file mode 100644 index 761e32206..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.spotify.navbar - -import app.revanced.patcher.fingerprint -import app.revanced.util.literal -import com.android.tools.smali.dexlib2.AccessFlags - -internal val addNavBarItemFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - literal { showBottomNavigationItemsTextId } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt index c191c676b..ddc92bcc4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt @@ -1,50 +1,12 @@ package app.revanced.patches.spotify.navbar -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.shared.misc.mapping.get -import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings - -internal var showBottomNavigationItemsTextId = -1L - private set -internal var premiumTabId = -1L - private set - -private val premiumNavbarTabResourcePatch = resourcePatch { - dependsOn(resourceMappingPatch) - - execute { - premiumTabId = resourceMappings["id", "premium_tab"] - - showBottomNavigationItemsTextId = resourceMappings[ - "bool", - "show_bottom_navigation_items_text", - ] - } -} +import app.revanced.patches.spotify.misc.unlockPremiumPatch +@Deprecated("Superseded by unlockPremiumPatch", ReplaceWith("unlockPremiumPatch")) @Suppress("unused") val premiumNavbarTabPatch = bytecodePatch( - name = "Premium navbar tab", description = "Hides the premium tab from the navigation bar.", ) { - dependsOn(premiumNavbarTabResourcePatch) - - compatibleWith("com.spotify.music") - - // If the navigation bar item is the premium tab, do not add it. - execute { - addNavBarItemFingerprint.method.addInstructions( - 0, - """ - const v1, $premiumTabId - if-ne p5, v1, :continue - return-void - :continue - nop - """, - ) - } + dependsOn(unlockPremiumPatch) }