mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-22 18:23:59 +00:00
feat(Spotify): Remove support for old versions (#5404)
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
package com.spotify.useraccount.v1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for target 8.6.98.900. Class is still present in newer app targets.
|
|
||||||
*/
|
|
||||||
public class AccountAttribute {
|
|
||||||
public Object value_;
|
|
||||||
}
|
|
||||||
@@ -6,12 +6,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import java.util.logging.Logger
|
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch;"
|
"Lapp/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch;"
|
||||||
@@ -26,13 +24,6 @@ val hideCreateButtonPatch = bytecodePatch(
|
|||||||
dependsOn(sharedExtensionPatch)
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
Logger.getLogger(this::class.java.name).warning(
|
|
||||||
"Create button does not exist in legacy app target. No changes applied."
|
|
||||||
)
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
val oldNavigationBarAddItemMethod = oldNavigationBarAddItemFingerprint.originalMethodOrNull
|
val oldNavigationBarAddItemMethod = oldNavigationBarAddItemFingerprint.originalMethodOrNull
|
||||||
// Only throw the fingerprint error when oldNavigationBarAddItemMethod does not exist.
|
// Only throw the fingerprint error when oldNavigationBarAddItemMethod does not exist.
|
||||||
val navigationBarItemSetClassDef = if (oldNavigationBarAddItemMethod == null) {
|
val navigationBarItemSetClassDef = if (oldNavigationBarAddItemMethod == null) {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||||||
import app.revanced.patcher.patch.resourcePatch
|
import app.revanced.patcher.patch.resourcePatch
|
||||||
import app.revanced.patcher.patch.stringOption
|
import app.revanced.patcher.patch.stringOption
|
||||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.*
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
@@ -19,12 +19,6 @@ private val customThemeBytecodePatch = bytecodePatch {
|
|||||||
dependsOn(sharedExtensionPatch)
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
// Bytecode changes are not needed for legacy app target.
|
|
||||||
// Player background color is changed with existing resource patch.
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
val colorSpaceUtilsClassDef = colorSpaceUtilsClassFingerprint.originalClassDef
|
val colorSpaceUtilsClassDef = colorSpaceUtilsClassFingerprint.originalClassDef
|
||||||
|
|
||||||
// Hook a util method that converts ARGB to RGBA in the sRGB color space to replace hardcoded accent colors.
|
// Hook a util method that converts ARGB to RGBA in the sRGB color space to replace hardcoded accent colors.
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package app.revanced.patches.spotify.lite.ondemand
|
|
||||||
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import app.revanced.patcher.fingerprint
|
|
||||||
|
|
||||||
internal val onDemandFingerprint = fingerprint(fuzzyPatternScanThreshold = 2) {
|
|
||||||
returns("L")
|
|
||||||
parameters()
|
|
||||||
opcodes(
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.GOTO,
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.IPUT,
|
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,9 @@
|
|||||||
package app.revanced.patches.spotify.lite.ondemand
|
package app.revanced.patches.spotify.lite.ondemand
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
|
||||||
@Deprecated("Patch no longer works and will be deleted soon")
|
@Deprecated("Patch no longer works and will be deleted soon")
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val onDemandPatch = bytecodePatch(
|
val onDemandPatch = bytecodePatch(
|
||||||
description = "Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.",
|
description = "Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.",
|
||||||
) {
|
)
|
||||||
compatibleWith("com.spotify.lite")
|
|
||||||
|
|
||||||
execute {
|
|
||||||
// Spoof a premium account
|
|
||||||
|
|
||||||
onDemandFingerprint.method.addInstruction(
|
|
||||||
onDemandFingerprint.patternMatch!!.endIndex - 1,
|
|
||||||
"const/4 v0, 0x2",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package app.revanced.patches.spotify.misc
|
|||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
@@ -13,25 +12,13 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
|||||||
|
|
||||||
context(BytecodePatchContext)
|
context(BytecodePatchContext)
|
||||||
internal val accountAttributeFingerprint get() = fingerprint {
|
internal val accountAttributeFingerprint get() = fingerprint {
|
||||||
custom { _, classDef ->
|
custom { _, classDef -> classDef.type == "Lcom/spotify/remoteconfig/internal/AccountAttribute;" }
|
||||||
classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
"Lcom/spotify/useraccount/v1/AccountAttribute;"
|
|
||||||
} else {
|
|
||||||
"Lcom/spotify/remoteconfig/internal/AccountAttribute;"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context(BytecodePatchContext)
|
context(BytecodePatchContext)
|
||||||
internal val productStateProtoGetMapFingerprint get() = fingerprint {
|
internal val productStateProtoGetMapFingerprint get() = fingerprint {
|
||||||
returns("Ljava/util/Map;")
|
returns("Ljava/util/Map;")
|
||||||
custom { _, classDef ->
|
custom { _, classDef -> classDef.type == "Lcom/spotify/remoteconfig/internal/ProductStateProto;" }
|
||||||
classDef.type == if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
"Lcom/spotify/ucs/proto/v0/UcsResponseWrapper${'$'}AccountAttributesResponse;"
|
|
||||||
} else {
|
|
||||||
"Lcom/spotify/remoteconfig/internal/ProductStateProto;"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val buildQueryParametersFingerprint = fingerprint {
|
internal val buildQueryParametersFingerprint = fingerprint {
|
||||||
@@ -90,14 +77,14 @@ internal val contextFromJsonFingerprint = fingerprint {
|
|||||||
)
|
)
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
method.name == "fromJson" &&
|
method.name == "fromJson" &&
|
||||||
classDef.endsWith("voiceassistants/playermodels/ContextJsonAdapter;")
|
classDef.type.endsWith("voiceassistants/playermodels/ContextJsonAdapter;")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val readPlayerOptionOverridesFingerprint = fingerprint {
|
internal val readPlayerOptionOverridesFingerprint = fingerprint {
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
method.name == "readPlayerOptionOverrides" &&
|
method.name == "readPlayerOptionOverrides" &&
|
||||||
classDef.endsWith("voiceassistants/playermodels/PreparePlayOptionsJsonAdapter;")
|
classDef.type.endsWith("voiceassistants/playermodels/PreparePlayOptionsJsonAdapter;")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,21 +106,21 @@ internal val abstractProtobufListEnsureIsMutableFingerprint = fingerprint {
|
|||||||
|
|
||||||
internal fun structureGetSectionsFingerprint(className: String) = fingerprint {
|
internal fun structureGetSectionsFingerprint(className: String) = fingerprint {
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
classDef.endsWith(className) && method.indexOfFirstInstruction {
|
classDef.type.endsWith(className) && method.indexOfFirstInstruction {
|
||||||
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.name == "sections_"
|
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.name == "sections_"
|
||||||
} >= 0
|
} >= 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val homeSectionFingerprint = fingerprint {
|
internal val homeSectionFingerprint = fingerprint {
|
||||||
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
|
custom { _, classDef -> classDef.type.endsWith("homeapi/proto/Section;") }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val homeStructureGetSectionsFingerprint =
|
internal val homeStructureGetSectionsFingerprint =
|
||||||
structureGetSectionsFingerprint("homeapi/proto/HomeStructure;")
|
structureGetSectionsFingerprint("homeapi/proto/HomeStructure;")
|
||||||
|
|
||||||
internal val browseSectionFingerprint = fingerprint {
|
internal val browseSectionFingerprint = fingerprint {
|
||||||
custom { _, classDef-> classDef.endsWith("browsita/v1/resolved/Section;") }
|
custom { _, classDef-> classDef.type.endsWith("browsita/v1/resolved/Section;") }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val browseStructureGetSectionsFingerprint =
|
internal val browseStructureGetSectionsFingerprint =
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
|||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.patch.stringOption
|
import app.revanced.patcher.patch.stringOption
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
@@ -57,16 +56,10 @@ val changeLyricsProviderPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
Logger.getLogger(this::class.java.name).severe(
|
|
||||||
"Change lyrics provider patch is not supported for this target version."
|
|
||||||
)
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
val httpClientBuilderMethod = httpClientBuilderFingerprint.originalMethod
|
val httpClientBuilderMethod = httpClientBuilderFingerprint.originalMethod
|
||||||
|
|
||||||
// region Create a modified copy of the HTTP client builder method with the custom lyrics provider host.
|
// region Create a modified copy of the HTTP client builder method with the custom lyrics provider host.
|
||||||
|
|
||||||
val patchedHttpClientBuilderMethod = with(httpClientBuilderMethod) {
|
val patchedHttpClientBuilderMethod = with(httpClientBuilderMethod) {
|
||||||
val invokeBuildUrlIndex = indexOfFirstInstructionOrThrow {
|
val invokeBuildUrlIndex = indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>()?.returnType == "Lokhttp3/HttpUrl;"
|
getReference<MethodReference>()?.returnType == "Lokhttp3/HttpUrl;"
|
||||||
@@ -89,9 +82,11 @@ val changeLyricsProviderPatch = bytecodePatch(
|
|||||||
httpClientBuilderFingerprint.classDef.methods.add(this)
|
httpClientBuilderFingerprint.classDef.methods.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
// region Replace the call to the HTTP client builder method used exclusively for lyrics by the modified one.
|
// region Replace the call to the HTTP client builder method used exclusively for lyrics by the modified one.
|
||||||
|
|
||||||
getLyricsHttpClientFingerprint(httpClientBuilderMethod).method.apply {
|
getLyricsHttpClientFingerprint(httpClientBuilderMethod).method.apply {
|
||||||
val getLyricsHttpClientIndex = indexOfFirstInstructionOrThrow {
|
val getLyricsHttpClientIndex = indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>() == httpClientBuilderMethod
|
getReference<MethodReference>() == httpClientBuilderMethod
|
||||||
@@ -118,6 +113,7 @@ val changeLyricsProviderPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ internal val shareCopyUrlFingerprint = fingerprint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val shareCopyUrlLegacyFingerprint = fingerprint {
|
internal val oldShareCopyUrlFingerprint = fingerprint {
|
||||||
returns("Ljava/lang/Object;")
|
returns("Ljava/lang/Object;")
|
||||||
parameters("Ljava/lang/Object;")
|
parameters("Ljava/lang/Object;")
|
||||||
strings("clipboard", "createNewSession failed")
|
strings("clipboard", "createNewSession failed")
|
||||||
@@ -38,7 +38,7 @@ internal val formatAndroidShareSheetUrlFingerprint = fingerprint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val formatAndroidShareSheetUrlLegacyFingerprint = fingerprint {
|
internal val oldFormatAndroidShareSheetUrlFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC)
|
accessFlags(AccessFlags.PUBLIC)
|
||||||
returns("Ljava/lang/String;")
|
returns("Ljava/lang/String;")
|
||||||
parameters("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;")
|
parameters("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;")
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package app.revanced.patches.spotify.misc.privacy
|
package app.revanced.patches.spotify.misc.privacy
|
||||||
|
|
||||||
import app.revanced.patcher.Fingerprint
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
@@ -28,10 +26,10 @@ val sanitizeSharingLinksPatch = bytecodePatch(
|
|||||||
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
|
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
"sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;"
|
"sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;"
|
||||||
|
|
||||||
val copyFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
val copyFingerprint = if (shareCopyUrlFingerprint.originalMethodOrNull != null) {
|
||||||
shareCopyUrlLegacyFingerprint
|
|
||||||
} else {
|
|
||||||
shareCopyUrlFingerprint
|
shareCopyUrlFingerprint
|
||||||
|
} else {
|
||||||
|
oldShareCopyUrlFingerprint
|
||||||
}
|
}
|
||||||
|
|
||||||
copyFingerprint.method.apply {
|
copyFingerprint.method.apply {
|
||||||
@@ -50,15 +48,10 @@ val sanitizeSharingLinksPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
|
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
|
||||||
val shareUrlParameter : String
|
val shareUrlParameter: String
|
||||||
val shareSheetFingerprint : Fingerprint
|
val shareSheetFingerprint = if (formatAndroidShareSheetUrlFingerprint.originalMethodOrNull != null) {
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
val methodAccessFlags = formatAndroidShareSheetUrlFingerprint.originalMethod
|
||||||
shareSheetFingerprint = formatAndroidShareSheetUrlLegacyFingerprint
|
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags.accessFlags)) {
|
||||||
shareUrlParameter = "p2"
|
|
||||||
} else {
|
|
||||||
shareSheetFingerprint = formatAndroidShareSheetUrlFingerprint
|
|
||||||
val methodAccessFlags = formatAndroidShareSheetUrlFingerprint.originalMethod.accessFlags
|
|
||||||
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags)) {
|
|
||||||
// In newer implementations the method is static, so p0 is not `this`.
|
// In newer implementations the method is static, so p0 is not `this`.
|
||||||
"p1"
|
"p1"
|
||||||
} else {
|
} else {
|
||||||
@@ -66,6 +59,11 @@ val sanitizeSharingLinksPatch = bytecodePatch(
|
|||||||
// For that reason, add one to the parameter register.
|
// For that reason, add one to the parameter register.
|
||||||
"p2"
|
"p2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatAndroidShareSheetUrlFingerprint
|
||||||
|
} else {
|
||||||
|
shareUrlParameter = "p2"
|
||||||
|
oldFormatAndroidShareSheetUrlFingerprint
|
||||||
}
|
}
|
||||||
|
|
||||||
shareSheetFingerprint.method.addInstructions(
|
shareSheetFingerprint.method.addInstructions(
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package app.revanced.patches.spotify.misc.widgets
|
package app.revanced.patches.spotify.misc.widgets
|
||||||
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
import java.util.logging.Logger
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val fixThirdPartyLaunchersWidgets = bytecodePatch(
|
val fixThirdPartyLaunchersWidgets = bytecodePatch(
|
||||||
@@ -13,14 +11,6 @@ val fixThirdPartyLaunchersWidgets = bytecodePatch(
|
|||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
|
||||||
// The permission check does not exist in legacy versions.
|
|
||||||
Logger.getLogger(this::class.java.name).warning(
|
|
||||||
"Legacy app target does not have any third party launcher restrictions. No changes applied."
|
|
||||||
)
|
|
||||||
return@execute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only system app launchers are granted the BIND_APPWIDGET permission.
|
// Only system app launchers are granted the BIND_APPWIDGET permission.
|
||||||
// Override the method that checks for it to always return true, as this permission is not actually required
|
// Override the method that checks for it to always return true, as this permission is not actually required
|
||||||
// for the widgets to work.
|
// for the widgets to work.
|
||||||
|
|||||||
@@ -1,38 +1,15 @@
|
|||||||
package app.revanced.patches.spotify.shared
|
package app.revanced.patches.spotify.shared
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;"
|
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 {
|
internal val mainActivityOnCreateFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returns("V")
|
returns("V")
|
||||||
parameters("Landroid/os/Bundle;")
|
parameters("Landroid/os/Bundle;")
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
method.name == "onCreate" && (classDef.type == SPOTIFY_MAIN_ACTIVITY
|
method.name == "onCreate" && classDef.type == SPOTIFY_MAIN_ACTIVITY
|
||||||
|| classDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var isLegacyAppTarget: Boolean? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If patching a legacy 8.x target. This may also be set if patching slightly older/newer app targets,
|
|
||||||
* but the only legacy target of interest is 8.6.98.900 as it's the last version that
|
|
||||||
* supports Spotify integration on Kenwood/Pioneer car stereos.
|
|
||||||
*/
|
|
||||||
context(BytecodePatchContext)
|
|
||||||
internal val IS_SPOTIFY_LEGACY_APP_TARGET
|
|
||||||
get(): Boolean {
|
|
||||||
if (isLegacyAppTarget == null) {
|
|
||||||
isLegacyAppTarget = mainActivityOnCreateFingerprint.originalClassDef.type == SPOTIFY_MAIN_ACTIVITY_LEGACY
|
|
||||||
}
|
|
||||||
return isLegacyAppTarget!!
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user