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)
}