fix(Spotify): Remove ads sections from home (#4722)

Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
This commit is contained in:
Nuckyz
2025-04-04 09:32:40 -03:00
committed by GitHub
parent 36772b8b2e
commit 628d18489c
3 changed files with 42 additions and 13 deletions

View File

@@ -0,0 +1,7 @@
package com.spotify.home.evopage.homeapi.proto;
public final class Section {
public static final int VIDEO_BRAND_AD_FIELD_NUMBER = 20;
public static final int IMAGE_BRAND_AD_FIELD_NUMBER = 21;
public int featureTypeCase_;
}

View File

@@ -1,16 +1,16 @@
package app.revanced.patches.spotify.misc
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val accountAttributeFingerprint = fingerprint {
custom { _, c -> c.endsWith("internal/AccountAttribute;") }
custom { _, classDef -> classDef.endsWith("internal/AccountAttribute;") }
}
internal val productStateProtoFingerprint = fingerprint {
returns("Ljava/util/Map;")
custom { _, classDef ->
classDef.endsWith("ProductStateProto;")
}
custom { _, classDef -> classDef.endsWith("ProductStateProto;") }
}
internal val buildQueryParametersFingerprint = fingerprint {
@@ -21,3 +21,17 @@ internal val contextMenuExperimentsFingerprint = fingerprint {
parameters("L")
strings("remove_ads_upsell_enabled")
}
internal val homeSectionFingerprint = fingerprint {
custom { _, classDef -> classDef.endsWith("homeapi/proto/Section;") }
}
internal val protobufListsFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
custom { method, _ -> method.name == "emptyProtobufList" }
}
internal val homeStructureFingerprint = fingerprint {
opcodes(Opcode.IGET_OBJECT, Opcode.RETURN_OBJECT)
custom { _, classDef -> classDef.endsWith("homeapi/proto/HomeStructure;") }
}

View File

@@ -53,7 +53,15 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
// All registers used by an instruction.
fun Instruction.getRegistersUsed() = when (this) {
is FiveRegisterInstruction -> listOf(registerC, registerD, registerE, registerF, registerG)
is FiveRegisterInstruction -> {
when (registerCount) {
1 -> listOf(registerC)
2 -> listOf(registerC, registerD)
3 -> listOf(registerC, registerD, registerE)
4 -> listOf(registerC, registerD, registerE, registerF)
else -> listOf(registerC, registerD, registerE, registerF, registerG)
}
}
is ThreeRegisterInstruction -> listOf(registerA, registerB, registerC)
is TwoRegisterInstruction -> listOf(registerA, registerB)
is OneRegisterInstruction -> listOf(registerA)
@@ -62,15 +70,15 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
}
// Register that is written to by an instruction.
fun Instruction.getRegisterWritten() = when (this) {
is ThreeRegisterInstruction -> registerA
is TwoRegisterInstruction -> registerA
is OneRegisterInstruction -> registerA
else -> throw IllegalStateException("Not a write instruction: $this")
fun Instruction.getWriteRegister() : Int {
// Two and three register instructions extend OneRegisterInstruction.
if (this is OneRegisterInstruction) return registerA
throw IllegalStateException("Not a write instruction: $this")
}
val writeOpcodes = EnumSet.of(
ARRAY_LENGTH,
INSTANCE_OF,
NEW_INSTANCE, NEW_ARRAY,
MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE, MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT,
MOVE_OBJECT_FROM16, MOVE_OBJECT_16, MOVE_RESULT, MOVE_RESULT_WIDE, MOVE_RESULT_OBJECT, MOVE_EXCEPTION,
@@ -140,7 +148,7 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
return freeRegister
}
if (bestFreeRegisterFound != null) {
return bestFreeRegisterFound;
return bestFreeRegisterFound
}
// Somehow every method register was read from before any register was wrote to.
@@ -151,14 +159,14 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
if (instruction.opcode in branchOpcodes) {
if (bestFreeRegisterFound != null) {
return bestFreeRegisterFound;
return bestFreeRegisterFound
}
// This method is simple and does not follow branching.
throw IllegalArgumentException("Encountered a branch statement before a free register could be found")
}
if (instruction.opcode in writeOpcodes) {
val writeRegister = instruction.getRegisterWritten()
val writeRegister = instruction.getWriteRegister()
if (writeRegister !in usedRegisters) {
// Verify the register is only used for write and not also as a parameter.