refactor: fix patch structure

This commit is contained in:
inotia00 2024-04-03 22:36:31 +09:00
parent 19adea7a86
commit 3a3ee89518
657 changed files with 4374 additions and 9404 deletions

View File

@ -3,63 +3,41 @@ package app.revanced.patches.music.account.component
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.account.component.fingerprints.MenuEntryFingerprint
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
@Suppress("unused")
object MenuComponentPatch : BaseBytecodePatch(
name = "Hide account menu",
description = "Adds the ability to hide account menu elements using a custom filter.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object MenuComponentPatch : BytecodePatch(
setOf(MenuEntryFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(MenuEntryFingerprint)
) {
override fun execute(context: BytecodeContext) {
MenuEntryFingerprint.result?.let {
it.mutableMethod.apply {
val textIndex = targetIndex("setText")
val viewIndex = targetIndex("addView")
val textIndex = getTargetIndexWithMethodReferenceName("setText")
val viewIndex = getTargetIndexWithMethodReferenceName("addView")
val textRegister = getInstruction<FiveRegisterInstruction>(textIndex).registerD
val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD
addInstruction(
textIndex + 1,
"invoke-static {v$textRegister, v$viewRegister}, $ACCOUNT->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V"
"invoke-static {v$textRegister, v$viewRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V"
)
}
} ?: throw MenuEntryFingerprint.exception
@ -81,12 +59,4 @@ object MenuComponentPatch : BytecodePatch(
"revanced_hide_account_menu"
)
}
private fun MutableMethod.targetIndex(descriptor: String): Int {
return implementation?.let {
it.instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == descriptor
}
} ?: throw PatchException("No Method Implementation found!")
}
}

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.account.component.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MenuEntry
import app.revanced.util.fingerprint.LiteralValueFingerprint
object MenuEntryFingerprint : LiteralValueFingerprint(
internal object MenuEntryFingerprint : LiteralValueFingerprint(
returnType = "V",
literalSupplier = { MenuEntry }
)

View File

@ -4,48 +4,29 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.account.handle.fingerprints.AccountSwitcherAccessibilityLabelFingerprint
import app.revanced.patches.music.account.handle.fingerprints.NamesInactiveAccountThumbnailSizeFingerprint
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object HandlePatch : BaseBytecodePatch(
name = "Hide handle",
description = "Adds an option to hide the handle in the account menu.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideHandlePatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
AccountSwitcherAccessibilityLabelFingerprint,
NamesInactiveAccountThumbnailSizeFingerprint
)
@ -64,7 +45,7 @@ object HideHandlePatch : BytecodePatch(
replaceInstruction(
setVisibilityIndex,
"invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT->hideHandle(Landroid/widget/TextView;I)V"
"invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Landroid/widget/TextView;I)V"
)
}
} ?: throw AccountSwitcherAccessibilityLabelFingerprint.exception
@ -79,7 +60,7 @@ object HideHandlePatch : BytecodePatch(
addInstructions(
targetIndex, """
invoke-static {v$targetRegister}, $ACCOUNT->hideHandle(Z)Z
invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z
move-result v$targetRegister
"""
)

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.account.handle.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
import app.revanced.util.fingerprint.LiteralValueFingerprint
object AccountSwitcherAccessibilityLabelFingerprint : LiteralValueFingerprint(
internal object AccountSwitcherAccessibilityLabelFingerprint : LiteralValueFingerprint(
returnType = "V",
parameters = listOf("L", "Ljava/lang/Object;"),
literalSupplier = { AccountSwitcherAccessibility }

View File

@ -4,7 +4,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.NamesIn
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
object NamesInactiveAccountThumbnailSizeFingerprint : LiteralValueFingerprint(
internal object NamesInactiveAccountThumbnailSizeFingerprint : LiteralValueFingerprint(
returnType = "V",
parameters = listOf("L", "Ljava/lang/Object;"),
opcodes = listOf(

View File

@ -4,83 +4,46 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.account.tos.fingerprints.TermsOfServiceFingerprint
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
@Suppress("unused")
object TermsContainerPatch : BaseBytecodePatch(
name = "Hide terms container",
description = "Adds an option to hide the terms of service container in the account menu.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object TermsContainerPatch : BytecodePatch(
setOf(TermsOfServiceFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TermsOfServiceFingerprint)
) {
override fun execute(context: BytecodeContext) {
TermsOfServiceFingerprint.result?.let {
it.mutableMethod.apply {
var insertIndex = 0
val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V")
val visibilityRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
for (index in implementation!!.instructions.size - 1 downTo 0) {
if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue
val targetReference =
getInstruction<ReferenceInstruction>(index).reference.toString()
if (targetReference.endsWith("/PrivacyTosFooter;->setVisibility(I)V")) {
insertIndex = index
val visibilityRegister =
getInstruction<Instruction35c>(insertIndex).registerD
addInstruction(
index + 1,
"const/4 v$visibilityRegister, 0x0"
)
addInstructions(
index, """
invoke-static {}, $ACCOUNT->hideTermsContainer()I
move-result v$visibilityRegister
"""
)
break
}
}
if (insertIndex == 0)
throw PatchException("target Instruction not found!")
addInstruction(
insertIndex + 1,
"const/4 v$visibilityRegister, 0x0"
)
addInstructions(
insertIndex, """
invoke-static {}, $ACCOUNT_CLASS_DESCRIPTOR->hideTermsContainer()I
move-result v$visibilityRegister
"""
)
}
} ?: throw TermsOfServiceFingerprint.exception

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.account.tos.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TosFooter
import app.revanced.util.fingerprint.LiteralValueFingerprint
object TermsOfServiceFingerprint : LiteralValueFingerprint(
internal object TermsOfServiceFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
literalSupplier = { TosFooter }
)

View File

@ -6,91 +6,68 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.actionbar.component.fingerprints.ActionBarComponentFingerprint
import app.revanced.patches.music.actionbar.component.fingerprints.LikeDislikeContainerFingerprint
import app.revanced.patches.music.actionbar.component.fingerprints.LikeDislikeContainerVisibilityFingerprint
import app.revanced.patches.music.utils.integrations.Constants.ACTIONBAR
import app.revanced.patches.music.utils.integrations.Constants.ACTIONBAR_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDislikeContainer
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import kotlin.math.min
@Patch(
@Suppress("unused")
object ActionBarComponentPatch : BaseBytecodePatch(
name = "Hide action bar component",
description = "Adds options to hide action bar components and replace the offline download button with an external download button.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class,
VideoInformationPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object ActionBarComponentPatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
ActionBarComponentFingerprint,
LikeDislikeContainerFingerprint
)
) {
private var spannedReference = ""
override fun execute(context: BytecodeContext) {
ActionBarComponentFingerprint.result?.let {
it.mutableMethod.apply {
val instructions = implementation!!.instructions
// hook download button
val addViewIndex = instructions.indexOfLast { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addView"
}
val addViewIndex = getTargetIndexWithMethodReferenceName("addView")
val addViewRegister = getInstruction<FiveRegisterInstruction>(addViewIndex).registerD
addInstruction(
addViewIndex + 1,
"invoke-static {v$addViewRegister}, $ACTIONBAR->hookDownloadButton(Landroid/view/View;)V"
"invoke-static {v$addViewRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->hookDownloadButton(Landroid/view/View;)V"
)
// hide action button label
val noLabelIndex = instructions.indexOfFirst { instruction ->
val reference = (instruction as? ReferenceInstruction)?.reference.toString()
instruction.opcode == Opcode.INVOKE_DIRECT
val noLabelIndex = indexOfFirstInstruction {
val reference = (this as? ReferenceInstruction)?.reference.toString()
opcode == Opcode.INVOKE_DIRECT
&& reference.endsWith("<init>(Landroid/content/Context;)V")
&& !reference.contains("Lcom/google/android/libraries/youtube/common/ui/YouTubeButton;")
} - 2
val replaceIndex = instructions.indexOfFirst { instruction ->
val reference = (instruction as? ReferenceInstruction)?.reference.toString()
instruction.opcode == Opcode.INVOKE_DIRECT
val replaceIndex = indexOfFirstInstruction {
val reference = (this as? ReferenceInstruction)?.reference.toString()
opcode == Opcode.INVOKE_DIRECT
&& reference.endsWith("Lcom/google/android/libraries/youtube/common/ui/YouTubeButton;-><init>(Landroid/content/Context;)V")
} - 2
val replaceInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
@ -98,7 +75,7 @@ object ActionBarComponentPatch : BytecodePatch(
addInstructionsWithLabels(
replaceIndex + 1, """
invoke-static {}, $ACTIONBAR->hideActionBarLabel()Z
invoke-static {}, $ACTIONBAR_CLASS_DESCRIPTOR->hideActionBarLabel()Z
move-result v${replaceInstruction.registerA}
if-nez v${replaceInstruction.registerA}, :hidden
iget-object v${replaceInstruction.registerA}, v${replaceInstruction.registerB}, $replaceReference
@ -107,21 +84,16 @@ object ActionBarComponentPatch : BytecodePatch(
removeInstruction(replaceIndex)
// hide action button
val hasNextIndex = instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "hasNext"
}
val hasNextIndex = getTargetIndexWithMethodReferenceName("hasNext")
val freeRegister = min(implementation!!.registerCount - parameters.size - 2, 15)
val spannedIndex = instructions.indexOfFirst { instruction ->
spannedReference = (instruction as? ReferenceInstruction)?.reference.toString()
spannedReference.endsWith("Landroid/text/Spanned;")
}
val spannedIndex = getTargetIndexWithReference(")Landroid/text/Spanned;")
val spannedRegister = getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference
addInstructionsWithLabels(
spannedIndex + 1, """
invoke-static {}, $ACTIONBAR->hideActionButton()Z
invoke-static {}, $ACTIONBAR_CLASS_DESCRIPTOR->hideActionButton()Z
move-result v$freeRegister
if-nez v$freeRegister, :hidden
invoke-static {v$spannedRegister}, $spannedReference
@ -138,12 +110,12 @@ object ActionBarComponentPatch : BytecodePatch(
addInstruction(
buttonTypeIndex + 2,
"invoke-static {v$buttonTypeRegister}, $ACTIONBAR->setButtonType(Ljava/lang/Object;)V"
"invoke-static {v$buttonTypeRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->setButtonType(Ljava/lang/Object;)V"
)
addInstruction(
buttonTypeDownloadIndex,
"invoke-static {v$buttonTypeDownloadRegister}, $ACTIONBAR->setButtonTypeDownload(I)V"
"invoke-static {v$buttonTypeDownloadRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->setButtonTypeDownload(I)V"
)
}
} ?: throw ActionBarComponentFingerprint.exception
@ -163,7 +135,7 @@ object ActionBarComponentPatch : BytecodePatch(
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $ACTIONBAR->hideLikeDislikeButton(Z)Z
invoke-static {v$targetRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->hideLikeDislikeButton(Z)Z
move-result v$targetRegister
"""
)
@ -176,7 +148,7 @@ object ActionBarComponentPatch : BytecodePatch(
addInstruction(
insertIndex + 1,
"invoke-static {v$insertRegister}, $ACTIONBAR->hideLikeDislikeButton(Landroid/view/View;)V"
"invoke-static {v$insertRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->hideLikeDislikeButton(Landroid/view/View;)V"
)
}
} ?: throw LikeDislikeContainerFingerprint.exception

View File

@ -5,7 +5,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ActionBarComponentFingerprint : LiteralValueFingerprint(
internal object ActionBarComponentFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L", "L"),

View File

@ -5,7 +5,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDis
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object LikeDislikeContainerFingerprint : LiteralValueFingerprint(
internal object LikeDislikeContainerFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
literalSupplier = { LikeDislikeContainer }

View File

@ -4,17 +4,14 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint
import app.revanced.patches.music.ads.general.fingerprints.InterstitialsContainerFingerprint
import app.revanced.patches.music.ads.general.fingerprints.NotifierShelfFingerprint
import app.revanced.patches.music.ads.general.fingerprints.ShowDialogCommandFingerprint
import app.revanced.patches.music.ads.music.MusicAdsPatch
import app.revanced.patches.music.navigation.component.NavigationBarComponentPatch
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer
@ -25,39 +22,21 @@ import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.exception
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object GeneralAdsPatch : BaseBytecodePatch(
name = "Hide general ads",
description = "Adds options to hide general ads.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
MusicAdsPatch::class,
NavigationBarComponentPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object GeneralAdsPatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
FloatingLayoutFingerprint,
InterstitialsContainerFingerprint,
NotifierShelfFingerprint,
@ -103,14 +82,6 @@ object GeneralAdsPatch : BytecodePatch(
it.mutableMethod.apply {
// In this method, custom dialog is created and shown.
// There were no issues despite adding “return-void” to the first index.
//
// If an issue occurs due to patching due to server-side changes in the future,
// Find the instruction whose name is "show" in [MethodReference] and click the 'AlertDialog.BUTTON_POSITIVE' button.
//
// In this case, an instruction for 'getButton' must be added to smali, not in integrations
// (This custom dialog cannot be cast to [AlertDialog] or [Dialog])
//
// See the comments below.
addInstructionsWithLabels(
0,
"""
@ -121,33 +92,38 @@ object GeneralAdsPatch : BytecodePatch(
""", ExternalLabel("show", getInstruction(0))
)
/*
val dialogIndex = getTargetIndexWithMethodReferenceName("show")
val dialogReference = getInstruction<ReferenceInstruction>(dialogIndex).reference
val dialogDefiningClass = (dialogReference as MethodReference).definingClass
val getButtonMethod = context.findClass(dialogDefiningClass)!!
.mutableClass.methods.first { method ->
method.parameters == listOf("I")
&& method.returnType == "Landroid/widget/Button;"
}
val getButtonCall = dialogDefiningClass + "->" + getButtonMethod.name + "(I)Landroid/widget/Button;"
// If an issue occurs due to patching due to server-side changes in the future,
// Find the instruction whose name is "show" in [MethodReference] and click the 'AlertDialog.BUTTON_POSITIVE' button.
//
// In this case, an instruction for 'getButton' must be added to smali, not in integrations
// (This custom dialog cannot be cast to [AlertDialog] or [Dialog])
//
// See the comments below.
val dialogRegister = getInstruction<FiveRegisterInstruction>(dialogIndex).registerC
val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ)
val freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA
// val dialogIndex = getTargetIndexWithMethodReferenceName("show")
// val dialogReference = getInstruction<ReferenceInstruction>(dialogIndex).reference
// val dialogDefiningClass = (dialogReference as MethodReference).definingClass
// val getButtonMethod = context.findClass(dialogDefiningClass)!!
// .mutableClass.methods.first { method ->
// method.parameters == listOf("I")
// && method.returnType == "Landroid/widget/Button;"
// }
// val getButtonCall = dialogDefiningClass + "->" + getButtonMethod.name + "(I)Landroid/widget/Button;"
// val dialogRegister = getInstruction<FiveRegisterInstruction>(dialogIndex).registerC
// val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ)
// val freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA
addInstructions(
dialogIndex + 1, """
# Get the 'AlertDialog.BUTTON_POSITIVE' from custom dialog
# Since this custom dialog cannot be cast to AlertDialog or Dialog,
# It should come from smali, not integrations.
const/4 v$freeRegister, -0x1
invoke-virtual {v$dialogRegister, $freeRegister}, $getButtonCall
move-result-object $freeRegister
invoke-static {$freeRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/Button;)V
"""
)
*/
// addInstructions(
// dialogIndex + 1, """
// # Get the 'AlertDialog.BUTTON_POSITIVE' from custom dialog
// # Since this custom dialog cannot be cast to AlertDialog or Dialog,
// # It should come from smali, not integrations.
// const/4 v$freeRegister, -0x1
// invoke-virtual {v$dialogRegister, $freeRegister}, $getButtonCall
// move-result-object $freeRegister
// invoke-static {$freeRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/Button;)V
// """
// )
}
} ?: throw ShowDialogCommandFingerprint.exception

View File

@ -5,7 +5,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Floatin
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object FloatingLayoutFingerprint : LiteralValueFingerprint(
internal object FloatingLayoutFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.ads.general.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
import app.revanced.util.fingerprint.LiteralValueFingerprint
object InterstitialsContainerFingerprint : LiteralValueFingerprint(
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
returnType = "V",
strings= listOf("overlay_controller_param"),
literalSupplier = { InterstitialsContainer }

View File

@ -7,7 +7,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicNo
import app.revanced.util.containsWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.AccessFlags
object NotifierShelfFingerprint : MethodFingerprint(
internal object NotifierShelfFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { methodDef, _ ->

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.ads.general.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
import app.revanced.util.fingerprint.LiteralValueFingerprint
object ShowDialogCommandFingerprint : LiteralValueFingerprint(
internal object ShowDialogCommandFingerprint : LiteralValueFingerprint(
returnType = "V",
literalSupplier = { SlidingDialogAnimation }
)

View File

@ -1,9 +1,9 @@
package app.revanced.patches.music.ads.music
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
import app.revanced.patches.shared.ads.AbstractAdsPatch
import app.revanced.patches.shared.ads.BaseAdsPatch
object MusicAdsPatch : AbstractAdsPatch(
object MusicAdsPatch : BaseAdsPatch(
"$ADS_PATH/MusicAdsPatch;",
"hideMusicAds"
)

View File

@ -2,61 +2,36 @@ package app.revanced.patches.music.flyoutpanel.compactdialog
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.flyoutpanel.compactdialog.fingerprints.DialogSolidFingerprint
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getWalkerMethod
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object CompactDialogPatch : BaseBytecodePatch(
name = "Enable compact dialog",
description = "Adds an option to enable the compact flyout menu on phones.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CompactDialogPatch : BytecodePatch(
setOf(DialogSolidFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(DialogSolidFingerprint)
) {
override fun execute(context: BytecodeContext) {
DialogSolidFingerprint.result?.let {
with(
context
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.endIndex, true)
.getMethod() as MutableMethod
) {
addInstructions(
2, """
invoke-static {p0}, $FLYOUT->enableCompactDialog(I)I
move-result p0
"""
)
}
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
walkerMethod.addInstructions(
2, """
invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I
move-result p0
"""
)
} ?: throw DialogSolidFingerprint.exception
SettingsPatch.addMusicPreference(

View File

@ -6,7 +6,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object DialogSolidFingerprint : LiteralValueFingerprint(
internal object DialogSolidFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),

View File

@ -3,14 +3,12 @@ package app.revanced.patches.music.flyoutpanel.component
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.flyoutpanel.component.fingerprints.EndButtonsContainerFingerprint
import app.revanced.patches.music.flyoutpanel.component.fingerprints.SleepTimerFingerprint
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer
import app.revanced.patches.music.utils.settings.CategoryType
@ -19,43 +17,29 @@ import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object FlyoutPanelPatch : BaseBytecodePatch(
name = "Hide flyout panel",
description = "Adds options to hide flyout panel components.",
dependencies = [
dependencies = setOf(
FlyoutPanelMenuItemPatch::class,
LithoFilterPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object FlyoutPanelPatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
EndButtonsContainerFingerprint,
SleepTimerFingerprint
)
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/PlayerFlyoutPanelsFilter;"
override fun execute(context: BytecodeContext) {
FlyoutPanelMenuItemPatch.hideComponents()
@ -67,7 +51,7 @@ object FlyoutPanelPatch : BytecodePatch(
addInstruction(
targetIndex + 1,
"invoke-static {v$targetRegister}, $FLYOUT->hideLikeDislikeContainer(Landroid/view/View;)V"
"invoke-static {v$targetRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideLikeDislikeContainer(Landroid/view/View;)V"
)
}
} ?: throw EndButtonsContainerFingerprint.exception
@ -234,7 +218,4 @@ object FlyoutPanelPatch : BytecodePatch(
"false"
)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/PlayerFlyoutPanelsFilter;"
}

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.flyoutpanel.component.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer
import app.revanced.util.fingerprint.LiteralValueFingerprint
object EndButtonsContainerFingerprint : LiteralValueFingerprint(
internal object EndButtonsContainerFingerprint : LiteralValueFingerprint(
returnType = "V",
literalSupplier = { EndButtonsContainer }
)

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.flyoutpanel.component.fingerprints
import app.revanced.util.fingerprint.LiteralValueFingerprint
object SleepTimerFingerprint : LiteralValueFingerprint(
internal object SleepTimerFingerprint : LiteralValueFingerprint(
returnType = "Z",
parameters = emptyList(),
literalSupplier = { 45372767 }

View File

@ -1,42 +1,24 @@
package app.revanced.patches.music.flyoutpanel.replace
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object ReplaceDismissQueuePatch : BaseBytecodePatch(
name = "Replace dismiss queue",
description = "Adds an option to replace \"Dismiss queue\" with \"Watch on YouTube\" in the flyout menu.",
dependencies = [
dependencies = setOf(
FlyoutPanelMenuItemPatch::class,
SettingsPatch::class,
VideoInformationPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object ReplaceDismissQueuePatch : BytecodePatch(emptySet()) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: BytecodeContext) {
FlyoutPanelMenuItemPatch.replaceComponents()

View File

@ -3,51 +3,32 @@ package app.revanced.patches.music.flyoutpanel.replace
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.flyoutpanel.replace.fingerprints.TouchOutsideFingerprint
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.overridespeed.OverrideSpeedHookPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
@Suppress("unused")
object ReplaceReportPatch : BaseBytecodePatch(
name = "Replace report",
description = "Adds an option to replace \"Report\" with \"Playback speed\" in the flyout menu.",
dependencies = [
dependencies = setOf(
FlyoutPanelMenuItemPatch::class,
OverrideSpeedHookPatch::class,
ReplaceReportResourcePatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object ReplaceReportPatch : BytecodePatch(
setOf(TouchOutsideFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TouchOutsideFingerprint)
) {
override fun execute(context: BytecodeContext) {
FlyoutPanelMenuItemPatch.replaceComponents()
@ -59,7 +40,7 @@ object ReplaceReportPatch : BytecodePatch(
addInstruction(
setOnClickListenerIndex + 1,
"sput-object v$setOnClickListenerRegister, $FLYOUT->touchOutSideView:Landroid/view/View;"
"sput-object v$setOnClickListenerRegister, $FLYOUT_CLASS_DESCRIPTOR->touchOutSideView:Landroid/view/View;"
)
}
} ?: throw TouchOutsideFingerprint.exception

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.flyoutpanel.replace.fingerprints
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TouchOutside
import app.revanced.util.fingerprint.LiteralValueFingerprint
object TouchOutsideFingerprint : LiteralValueFingerprint(
internal object TouchOutsideFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
literalSupplier = { TouchOutside }
)

View File

@ -8,7 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.flyoutpanel.shared.fingerprints.MenuItemFingerprint
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR
import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.indexOfFirstInstruction
@ -58,7 +58,7 @@ object FlyoutPanelMenuItemPatch : BytecodePatch(
addInstructionsWithLabels(
enumIndex + 1, """
invoke-static {v$enumRegister}, $FLYOUT->hideComponents(Ljava/lang/Enum;)Z
invoke-static {v$enumRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideComponents(Ljava/lang/Enum;)Z
move-result v$freeRegister
if-nez v$freeRegister, :hide
""", ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1))
@ -74,7 +74,7 @@ object FlyoutPanelMenuItemPatch : BytecodePatch(
addInstruction(
enumIndex + 1,
"invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V"
"invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V"
)
}
instructionAdded = true

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object MenuItemFingerprint : MethodFingerprint(
internal object MenuItemFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -1,37 +1,19 @@
package app.revanced.patches.music.general.amoled
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.shared.drawable.DrawableColorPatch
import app.revanced.util.patch.BaseResourcePatch
import org.w3c.dom.Element
@Patch(
@Suppress("DEPRECATION", "unused")
object AmoledPatch : BaseResourcePatch(
name = "Amoled",
description = "Applies a pure black theme to some components.",
dependencies = [DrawableColorPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
)
@Suppress("unused")
object AmoledPatch : ResourcePatch() {
dependencies = setOf(DrawableColorPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: ResourceContext) {
DrawableColorPatch.injectCall("$UTILS_PATH/DrawableColorPatch;->getColor(I)I")

View File

@ -0,0 +1,6 @@
package app.revanced.patches.music.general.autocaptions
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.shared.captions.BaseAutoCaptionsPatch
object AutoCaptionsBytecodePatch : BaseAutoCaptionsPatch(GENERAL_CLASS_DESCRIPTOR)

View File

@ -1,47 +1,27 @@
package app.revanced.patches.music.general.autocaptions
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.video.videoid.VideoIdPatch
import app.revanced.patches.shared.captions.AbstractAutoCaptionsPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object AutoCaptionsPatch : BaseResourcePatch(
name = "Disable auto captions",
description = "Adds an option to disable captions from being automatically enabled.",
dependencies = [
dependencies = setOf(
AutoCaptionsBytecodePatch::class,
SettingsPatch::class,
VideoIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
)
@Suppress("unused")
object AutoCaptionsPatch : AbstractAutoCaptionsPatch(
GENERAL
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: BytecodeContext) {
super.execute(context)
override fun execute(context: ResourceContext) {
VideoIdPatch.hookBackgroundPlayVideoId("$GENERAL->newVideoStarted(Ljava/lang/String;)V")
VideoIdPatch.hookBackgroundPlayVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.buttonshelf
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object ButtonShelfPatch : BaseResourcePatch(
name = "Hide button shelf",
description = "Adds an option to hide the button shelf from the homepage and explore tab.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideButtonShelfPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/ButtonShelfFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HideButtonShelfPatch : BytecodePatch(emptySet()) {
"false"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/ButtonShelfFilter;"
}

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.carouselshelf
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object CarouselShelfPatch : BaseResourcePatch(
name = "Hide carousel shelf",
description = "Adds an option to hide the carousel shelf from the homepage and explore tab.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideCarouselShelfPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/CarouselShelfFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HideCarouselShelfPatch : BytecodePatch(emptySet()) {
"false"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/CarouselShelfFilter;"
}

View File

@ -4,49 +4,30 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.castbutton.fingerprints.MediaRouteButtonFingerprint
import app.revanced.patches.music.general.castbutton.fingerprints.PlayerOverlayChipFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object CastButtonPatch : BaseBytecodePatch(
name = "Hide cast button",
description = "Adds an option to hide the cast button.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideCastButtonPatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
MediaRouteButtonFingerprint,
PlayerOverlayChipFingerprint
)
@ -63,7 +44,7 @@ object HideCastButtonPatch : BytecodePatch(
setVisibilityMethod?.apply {
addInstructions(
0, """
invoke-static {p1}, $GENERAL->hideCastButton(I)I
invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result p1
"""
)
@ -80,7 +61,7 @@ object HideCastButtonPatch : BytecodePatch(
addInstruction(
targetIndex + 1,
"invoke-static {v$targetRegister}, $GENERAL->hideCastButton(Landroid/view/View;)V"
"invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V"
)
}
} ?: throw PlayerOverlayChipFingerprint.exception

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object MediaRouteButtonFingerprint : MethodFingerprint(
internal object MediaRouteButtonFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
strings = listOf("MediaRouteButton")

View File

@ -5,7 +5,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerO
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object PlayerOverlayChipFingerprint : LiteralValueFingerprint(
internal object PlayerOverlayChipFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
literalSupplier = { PlayerOverlayChip }

View File

@ -3,45 +3,26 @@ package app.revanced.patches.music.general.categorybar
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.categorybar.fingerprints.ChipCloudFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object CategoryBarPatch : BaseBytecodePatch(
name = "Hide category bar",
description = "Adds an option to hide the category bar.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CategoryBarPatch : BytecodePatch(
setOf(ChipCloudFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(ChipCloudFingerprint)
) {
override fun execute(context: BytecodeContext) {
ChipCloudFingerprint.result?.let {
@ -51,7 +32,7 @@ object CategoryBarPatch : BytecodePatch(
addInstruction(
targetIndex + 1,
"invoke-static { v$targetRegister }, $GENERAL->hideCategoryBar(Landroid/view/View;)V"
"invoke-static { v$targetRegister }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBar(Landroid/view/View;)V"
)
}
} ?: throw ChipCloudFingerprint.exception

View File

@ -4,7 +4,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ChipClo
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
object ChipCloudFingerprint : LiteralValueFingerprint(
internal object ChipCloudFingerprint : LiteralValueFingerprint(
returnType = "V",
opcodes = listOf(
Opcode.CONST,

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.channelguidelines
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object ChannelGuidelinesPatch : BaseResourcePatch(
name = "Hide channel guidelines",
description = "Adds an option to hide the channel guidelines at the top of the comments section.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideChannelGuidelinesPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/ChannelGuidelinesFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HideChannelGuidelinesPatch : BytecodePatch(emptySet()) {
"true"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/ChannelGuidelinesFilter;"
}

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.customfilter
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object CustomFilterPatch : BaseResourcePatch(
name = "Enable custom filter",
description = "Adds a custom filter which can be used to hide layout components.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CustomFilterPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/CustomFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -49,10 +35,5 @@ object CustomFilterPatch : BytecodePatch(emptySet()) {
"revanced_custom_filter"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/CustomFilter;"
}

View File

@ -1,47 +0,0 @@
package app.revanced.patches.music.general.dialog
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.dialog.AbstractRemoveViewerDiscretionDialogPatch
@Patch(
name = "Remove viewer discretion dialog",
description = "Adds an option to remove the dialog that appears when opening a video that has been age-restricted " +
"by accepting it automatically. This does not bypass the age restriction.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object RemoveViewerDiscretionDialogPatch : AbstractRemoveViewerDiscretionDialogPatch(
GENERAL
) {
override fun execute(context: BytecodeContext) {
super.execute(context)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
"revanced_remove_viewer_discretion_dialog",
"false"
)
}
}

View File

@ -0,0 +1,6 @@
package app.revanced.patches.music.general.dialog
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.shared.dialog.BaseViewerDiscretionDialogPatch
object ViewerDiscretionDialogBytecodePatch : BaseViewerDiscretionDialogPatch(GENERAL_CLASS_DESCRIPTOR)

View File

@ -0,0 +1,28 @@
package app.revanced.patches.music.general.dialog
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.patch.BaseResourcePatch
@Suppress("unused")
object ViewerDiscretionDialogPatch : BaseResourcePatch(
name = "Remove viewer discretion dialog",
description = "Adds an option to remove the dialog that appears when opening a video that has been age-restricted " +
"by accepting it automatically. This does not bypass the age restriction.",
dependencies = setOf(
SettingsPatch::class,
ViewerDiscretionDialogBytecodePatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: ResourceContext) {
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
"revanced_remove_viewer_discretion_dialog",
"false"
)
}
}

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.emojipicker
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object EmojiPickerPatch : BaseResourcePatch(
name = "Hide emoji picker and time stamp",
description = "Adds an option to hide the emoji picker and time stamp when typing comments.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideEmojiPickerPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/EmojiPickerFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HideEmojiPickerPatch : BytecodePatch(emptySet()) {
"false"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/EmojiPickerFilter;"
}

View File

@ -3,46 +3,27 @@ package app.revanced.patches.music.general.floatingbutton
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.general.floatingbutton.fingerprints.FloatingButtonFingerprint
import app.revanced.patches.music.general.floatingbutton.fingerprints.FloatingButtonParentFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object FloatingButtonPatch : BaseBytecodePatch(
name = "Hide new playlist button",
description = "Adds an option to hide the \"New playlist\" button in the library.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object NewPlaylistButtonPatch : BytecodePatch(
setOf(FloatingButtonParentFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(FloatingButtonParentFingerprint)
) {
override fun execute(context: BytecodeContext) {
@ -56,7 +37,7 @@ object NewPlaylistButtonPatch : BytecodePatch(
it.mutableMethod.apply {
addInstructionsWithLabels(
1, """
invoke-static {}, $GENERAL->hideNewPlaylistButton()Z
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideNewPlaylistButton()Z
move-result v0
if-eqz v0, :show
return-void

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.general.floatingbutton.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object FloatingButtonFingerprint : MethodFingerprint(
internal object FloatingButtonFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L"),
opcodes = listOf(Opcode.AND_INT_LIT16)

View File

@ -5,7 +5,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object FloatingButtonParentFingerprint : LiteralValueFingerprint(
internal object FloatingButtonParentFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L"),

View File

@ -3,46 +3,27 @@ package app.revanced.patches.music.general.historybutton
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.historybutton.fingerprints.HistoryMenuItemFingerprint
import app.revanced.patches.music.general.historybutton.fingerprints.HistoryMenuItemOfflineTabFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
@Suppress("unused")
object HistoryButtonPatch : BaseBytecodePatch(
name = "Hide history button",
description = "Adds an option to hide the history button in the toolbar.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideHistoryButtonPatch : BytecodePatch(
setOf(
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
HistoryMenuItemFingerprint,
HistoryMenuItemOfflineTabFingerprint
)
@ -60,7 +41,7 @@ object HideHistoryButtonPatch : BytecodePatch(
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $GENERAL->hideHistoryButton(Z)Z
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHistoryButton(Z)Z
move-result v$insertRegister
"""
)

View File

@ -7,7 +7,7 @@ import app.revanced.util.containsWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object HistoryMenuItemFingerprint : MethodFingerprint(
internal object HistoryMenuItemFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/Menu;"),

View File

@ -8,7 +8,7 @@ import app.revanced.util.containsWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object HistoryMenuItemOfflineTabFingerprint : MethodFingerprint(
internal object HistoryMenuItemOfflineTabFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/Menu;"),

View File

@ -2,53 +2,41 @@ package app.revanced.patches.music.general.landscapemode
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patches.music.general.landscapemode.fingerprints.TabletIdentifierFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object LandScapeModePatch : BaseBytecodePatch(
name = "Enable landscape mode",
description = "Adds an option to enable landscape mode when rotating the screen on phones.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object LandScapeModePatch : BytecodePatch(
setOf(TabletIdentifierFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TabletIdentifierFingerprint)
) {
override fun execute(context: BytecodeContext) {
TabletIdentifierFingerprint.result?.let {
it.mutableMethod.addInstructions(
it.scanResult.patternScanResult!!.endIndex + 1, """
invoke-static {p0}, $GENERAL->enableLandScapeMode(Z)Z
move-result p0
"""
)
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->enableLandScapeMode(Z)Z
move-result v$targetRegister
"""
)
}
} ?: throw TabletIdentifierFingerprint.exception
SettingsPatch.addMusicPreference(

View File

@ -6,7 +6,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object TabletIdentifierFingerprint : LiteralValueFingerprint(
internal object TabletIdentifierFingerprint : LiteralValueFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),

View File

@ -3,53 +3,37 @@ package app.revanced.patches.music.general.oldstylelibraryshelf
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.oldstylelibraryshelf.fingerprints.BrowseIdFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getStringInstructionIndex
import app.revanced.util.getTargetIndexReversed
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Patch(
@Suppress("unused")
object OldStyleLibraryShelfPatch : BaseBytecodePatch(
name = "Enable old style library shelf",
description = "Adds an option to return the library tab to the old style.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object OldStyleLibraryShelfPatch : BytecodePatch(
setOf(BrowseIdFingerprint)
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(BrowseIdFingerprint)
) {
override fun execute(context: BytecodeContext) {
BrowseIdFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getStringInstructionIndex("FEmusic_offline") - 5
val stringIndex = getStringInstructionIndex("FEmusic_offline")
val targetIndex = getTargetIndexReversed(stringIndex, Opcode.IGET_OBJECT)
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $GENERAL->enableOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String;
invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->enableOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
"""
)

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object BrowseIdFingerprint : LiteralValueFingerprint(
internal object BrowseIdFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.playlistcard
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object PlaylistCardPatch : BaseResourcePatch(
name = "Hide playlist card",
description = "Adds an option to hide the playlist card from the homepage.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HidePlaylistCardPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/PlaylistCardFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HidePlaylistCardPatch : BytecodePatch(emptySet()) {
"false"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/PlaylistCardFilter;"
}

View File

@ -3,14 +3,12 @@ package app.revanced.patches.music.general.redirection
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.general.redirection.fingerprints.DislikeButtonOnClickListenerFingerprint
import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
@ -19,37 +17,20 @@ import app.revanced.util.getTargetIndexReversed
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.Reference
@Patch(
@Suppress("unused")
object DislikeRedirectionPatch : BaseBytecodePatch(
name = "Disable dislike redirection",
description = "Adds an option to disable redirection to the next track when clicking dislike button.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object DislikeRedirectionPatch : BytecodePatch(
setOf(
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
DislikeButtonOnClickListenerFingerprint,
PendingIntentReceiverFingerprint
)
@ -105,7 +86,7 @@ object DislikeRedirectionPatch : BytecodePatch(
addInstructionsWithLabels(
targetIndex + 1, """
invoke-static {}, $GENERAL->disableDislikeRedirection()Z
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->disableDislikeRedirection()Z
move-result v$insertRegister
if-nez v$insertRegister, :disable
""", ExternalLabel("disable", getInstruction(onClickIndex + 1))

View File

@ -1,42 +1,28 @@
package app.revanced.patches.music.general.sampleshelf
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object SampleShelfPatch : BaseResourcePatch(
name = "Hide sample shelf",
description = "Adds an option to hide the sample shelf from the homepage.",
dependencies = [
dependencies = setOf(
LithoFilterPatch::class,
SettingsPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideSampleShelfPatch : BytecodePatch(emptySet()) {
override fun execute(context: BytecodeContext) {
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/SampleShelfFilter;"
override fun execute(context: ResourceContext) {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.addMusicPreference(
CategoryType.GENERAL,
@ -44,10 +30,5 @@ object HideSampleShelfPatch : BytecodePatch(emptySet()) {
"false"
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
}
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/SampleShelfFilter;"
}

View File

@ -4,43 +4,24 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.startpage.fingerprints.ColdStartUpFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.utils.settings.SettingsPatch.contexts
import app.revanced.util.copyXmlNode
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object ChangeStartPagePatch : BaseBytecodePatch(
name = "Change start page",
description = "Adds an option to set which page the app opens in instead of the homepage.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object ChangeStartPagePatch : BytecodePatch(
setOf(ColdStartUpFingerprint)
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(ColdStartUpFingerprint)
) {
override fun execute(context: BytecodeContext) {
@ -51,7 +32,7 @@ object ChangeStartPagePatch : BytecodePatch(
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $GENERAL->changeStartPage(Ljava/lang/String;)Ljava/lang/String;
invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
return-object v$targetRegister
"""

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ColdStartUpFingerprint : MethodFingerprint(
internal object ColdStartUpFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -3,41 +3,22 @@ package app.revanced.patches.music.general.taptoupdate
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.general.taptoupdate.fingerprints.ContentPillInFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object TapToUpdateButtonPatch : BaseBytecodePatch(
name = "Hide tap to update button",
description = "Adds an option to hide the tap to update button.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideTapToUpdateButtonPatch : BytecodePatch(
setOf(ContentPillInFingerprint)
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(ContentPillInFingerprint)
) {
override fun execute(context: BytecodeContext) {
@ -46,7 +27,7 @@ object HideTapToUpdateButtonPatch : BytecodePatch(
addInstructionsWithLabels(
0,
"""
invoke-static {}, $GENERAL->hideTapToUpdateButton()Z
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideTapToUpdateButton()Z
move-result v0
if-eqz v0, :show
return-void

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.general.taptoupdate.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
object ContentPillInFingerprint : MethodFingerprint(
internal object ContentPillInFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf("Content pill VE is null")
)

View File

@ -2,38 +2,19 @@ package app.revanced.patches.music.general.tooltip
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.general.tooltip.fingerprints.TooltipContentViewFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object TooltipContentViewPatch : BaseBytecodePatch(
name = "Hide tooltip content",
description = "Hides the tooltip box that appears when opening the app for the first time.",
dependencies = [SharedResourceIdPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object TooltipContentViewPatch : BytecodePatch(
setOf(TooltipContentViewFingerprint)
dependencies = setOf(SharedResourceIdPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TooltipContentViewFingerprint)
) {
override fun execute(context: BytecodeContext) {

View File

@ -5,7 +5,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ToolTip
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object TooltipContentViewFingerprint : LiteralValueFingerprint(
internal object TooltipContentViewFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),

View File

@ -1,33 +1,23 @@
package app.revanced.patches.music.general.voicesearch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.voicesearch.AbstractVoiceSearchButtonPatch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object VoiceSearchButtonPatch : BaseResourcePatch(
name = "Hide voice search button",
description = "Hides the voice search button in the search bar.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
compatiblePackages = COMPATIBLE_PACKAGE,
use = false
)
@Suppress("unused")
object VoiceSearchButtonPatch : AbstractVoiceSearchButtonPatch(
arrayOf("search_toolbar_view.xml"),
arrayOf("height", "width")
)
) {
override fun execute(context: ResourceContext) {
context.patchXml(
arrayOf("search_toolbar_view.xml"),
arrayOf("height", "width")
)
}
}

View File

@ -2,38 +2,20 @@ package app.revanced.patches.music.layout.branding.icon
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
import app.revanced.util.patch.BaseResourcePatch
import java.io.File
import java.nio.file.Files
@Patch(
@Suppress("DEPRECATION", "unused")
object CustomBrandingIconPatch : BaseResourcePatch(
name = "Custom branding icon YouTube Music",
description = "Changes the YouTube Music app icon to the icon specified in options.json.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CustomBrandingIconPatch : ResourcePatch() {
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val DEFAULT_ICON_KEY = "Revancify Blue"
private val availableIcon = mapOf(

View File

@ -2,37 +2,17 @@ package app.revanced.patches.music.layout.branding.name
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST
import app.revanced.patches.shared.elements.AbstractRemoveStringsElementsPatch
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("DEPRECATION", "unused")
object CustomBrandingNamePatch : BaseResourcePatch(
name = "Custom branding name YouTube Music",
description = "Renames the YouTube Music app to the name specified in options.json.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CustomBrandingNamePatch : AbstractRemoveStringsElementsPatch(
LANGUAGE_LIST,
arrayOf("app_launcher_name", "app_name")
compatiblePackages = COMPATIBLE_PACKAGE
) {
private const val APP_NAME_NOTIFICATION = "ReVanced Extended Music"
private const val APP_NAME_LAUNCHER = "RVX Music"
@ -62,7 +42,11 @@ object CustomBrandingNamePatch : AbstractRemoveStringsElementsPatch(
)
override fun execute(context: ResourceContext) {
super.execute(context)
context.removeStringsElements(
LANGUAGE_LIST,
arrayOf("app_launcher_name", "app_name")
)
AppNameNotification?.let { notificationName ->
AppNameLauncher?.let { launcherName ->

View File

@ -1,33 +1,21 @@
package app.revanced.patches.music.layout.doubletapbackground
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.overlaybackground.AbstractOverlayBackgroundPatch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.shared.overlaybackground.OverlayBackgroundUtils.removeOverlayBackground
import app.revanced.util.patch.BaseResourcePatch
@Patch(
name = "Hide double tap overlay filter",
description = "Removes the dark overlay when double-tapping to seek.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
use = false
)
@Suppress("unused")
object DoubleTapOverlayBackgroundPatch : AbstractOverlayBackgroundPatch(
arrayOf("quick_seek_overlay.xml"),
arrayOf("tap_bloom_view", "dark_background")
)
object DoubleTapOverlayBackgroundPatch : BaseResourcePatch(
name = "Hide double tap overlay filter",
description = "Hides the dark overlay when double-tapping to seek.",
compatiblePackages = COMPATIBLE_PACKAGE,
use = false
) {
override fun execute(context: ResourceContext) {
context.removeOverlayBackground(
arrayOf("quick_seek_overlay.xml"),
arrayOf("tap_bloom_view", "dark_background")
)
}
}

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.overlayfilter.fingerprints.DesignBottomSheetDialogFingerprint
import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.integrations.IntegrationsPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.exception
@ -33,7 +33,7 @@ object OverlayFilterBytecodePatch : BytecodePatch(
insertIndex, """
invoke-virtual {p0}, $definingClass->getWindow()Landroid/view/Window;
move-result-object v$freeRegister
invoke-static {v$freeRegister}, $GENERAL->disableDimBehind(Landroid/view/Window;)V
invoke-static {v$freeRegister}, $GENERAL_CLASS_DESCRIPTOR->disableDimBehind(Landroid/view/Window;)V
"""
)
}

View File

@ -1,36 +1,17 @@
package app.revanced.patches.music.layout.overlayfilter
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.patch.BaseResourcePatch
@Patch(
name = "Disable overlay filter",
description = "Removes the dark overlay when comment, share, save to playlist, and flyout panels are open.",
dependencies = [OverlayFilterBytecodePatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
@Suppress("DEPRECATION", "unused")
object OverlayFilterPatch : BaseResourcePatch(
name = "Hide overlay filter",
description = "Hides the dark overlay when comment, share, save to playlist, and flyout panels are open.",
dependencies = setOf(OverlayFilterBytecodePatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
use = false
)
@Suppress("unused")
object OverlayFilterPatch : ResourcePatch() {
) {
override fun execute(context: ResourceContext) {
val styleFile = context["res/values/styles.xml"]

View File

@ -4,7 +4,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DesignB
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
object DesignBottomSheetDialogFingerprint : LiteralValueFingerprint(
internal object DesignBottomSheetDialogFingerprint : LiteralValueFingerprint(
returnType = "V",
parameters = emptyList(),
opcodes = listOf(

View File

@ -1,33 +1,21 @@
package app.revanced.patches.music.layout.doubletapbackground
package app.revanced.patches.music.layout.playeroverlay
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.overlaybackground.AbstractOverlayBackgroundPatch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.shared.overlaybackground.OverlayBackgroundUtils.removeOverlayBackground
import app.revanced.util.patch.BaseResourcePatch
@Patch(
name = "Hide player overlay filter",
description = "Removes the dark overlay when single-tapping player.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
use = false
)
@Suppress("unused")
object PlayerOverlayFilterPatch : AbstractOverlayBackgroundPatch(
arrayOf("music_controls_overlay.xml"),
arrayOf("player_control_screen")
)
object PlayerOverlayFilterPatch : BaseResourcePatch(
name = "Hide player overlay filter",
description = "Hides the dark overlay when single-tapping player.",
compatiblePackages = COMPATIBLE_PACKAGE,
use = false
) {
override fun execute(context: ResourceContext) {
context.removeOverlayBackground(
arrayOf("music_controls_overlay.xml"),
arrayOf("player_control_screen")
)
}
}

View File

@ -2,36 +2,17 @@ package app.revanced.patches.music.misc.backgroundplay
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.misc.backgroundplay.fingerprints.BackgroundPlaybackFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object BackgroundPlayPatch : BaseBytecodePatch(
name = "Background play",
description = "Enables playing music in the background.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object BackgroundPlayPatch : BytecodePatch(
setOf(BackgroundPlaybackFingerprint)
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(BackgroundPlaybackFingerprint)
) {
override fun execute(context: BytecodeContext) {

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object BackgroundPlaybackFingerprint : LiteralValueFingerprint(
internal object BackgroundPlaybackFingerprint : LiteralValueFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),

View File

@ -1,33 +1,15 @@
package app.revanced.patches.music.misc.bitrate
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("DEPRECATION", "unused")
object BitrateDefaultValuePatch : BaseResourcePatch(
name = "Bitrate default value",
description = "Sets the audio quality to \"Always High\" when you first install the app.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object BitrateDefaultValuePatch : ResourcePatch() {
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: ResourceContext) {
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
editor.file.getElementsByTagName("com.google.android.apps.youtube.music.ui.preference.PreferenceCategoryCompat")

View File

@ -1,47 +0,0 @@
package app.revanced.patches.music.misc.codecs
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.opus.AbstractOpusCodecsPatch
@Patch(
name = "Enable opus codec",
description = "Adds an option use the opus audio codec instead of the mp4a audio codec.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object CodecsUnlockPatch : AbstractOpusCodecsPatch(
"$MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z"
) {
override fun execute(context: BytecodeContext) {
super.execute(context)
SettingsPatch.addMusicPreference(
CategoryType.MISC,
"revanced_enable_opus_codec",
"true"
)
}
}

View File

@ -0,0 +1,8 @@
package app.revanced.patches.music.misc.codecs
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.shared.opus.BaseOpusCodecsPatch
object ForceOpusCodecBytecodePatch : BaseOpusCodecsPatch(
"$MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z"
)

View File

@ -0,0 +1,29 @@
package app.revanced.patches.music.misc.codecs
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.patch.BaseResourcePatch
@Suppress("unused")
object ForceOpusCodecPatch : BaseResourcePatch(
name = "Enable opus codec",
description = "Adds an option use the opus audio codec instead of the mp4a audio codec.",
dependencies = setOf(
ForceOpusCodecBytecodePatch::class,
SettingsPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: ResourceContext) {
SettingsPatch.addMusicPreference(
CategoryType.MISC,
"revanced_enable_opus_codec",
"true"
)
}
}

View File

@ -1,37 +1,19 @@
package app.revanced.patches.music.misc.debugging
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object DebuggingPatch : BaseResourcePatch(
name = "Enable debug logging",
description = "Adds an option to enable debug logging.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
],
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
use = false
)
@Suppress("unused")
object DebuggingPatch : ResourcePatch() {
) {
override fun execute(context: ResourceContext) {
SettingsPatch.addMusicPreference(

View File

@ -4,44 +4,25 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.misc.exclusiveaudio.fingerprints.DataSavingSettingsFragmentFingerprint
import app.revanced.patches.music.misc.exclusiveaudio.fingerprints.MusicBrowserServiceFingerprint
import app.revanced.patches.music.misc.exclusiveaudio.fingerprints.PodCastConfigFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.exception
import app.revanced.util.getStringInstructionIndex
import app.revanced.util.getWalkerMethod
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Patch(
@Suppress("unused")
object ExclusiveAudioPatch : BaseBytecodePatch(
name = "Exclusive audio playback",
description = "Unlocks the option to play music without video.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object ExclusiveAudioPatch : BytecodePatch(
setOf(
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
DataSavingSettingsFragmentFingerprint,
MusicBrowserServiceFingerprint,
PodCastConfigFingerprint
@ -64,19 +45,14 @@ object ExclusiveAudioPatch : BytecodePatch(
if (!targetReference.toString().endsWith("()Z")) continue
with(
context
.toMethodWalker(it.method)
.nextMethod(index, true)
.getMethod() as MutableMethod
) {
addInstructions(
0, """
const/4 v0, 0x1
return v0
"""
)
}
val walkerMethod = getWalkerMethod(context, index)
walkerMethod.addInstructions(
0, """
const/4 v0, 0x1
return v0
"""
)
break
}
}

View File

@ -2,9 +2,12 @@ package app.revanced.patches.music.misc.exclusiveaudio.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
object DataSavingSettingsFragmentFingerprint : MethodFingerprint(
internal object DataSavingSettingsFragmentFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("Landroid/os/Bundle;", "Ljava/lang/String;"),
strings = listOf("pref_key_dont_play_nma_video"),
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/DataSavingSettingsFragment;") && methodDef.name == "onCreatePreferences" }
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/DataSavingSettingsFragment;")
&& methodDef.name == "onCreatePreferences"
}
)

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object MusicBrowserServiceFingerprint : MethodFingerprint(
internal object MusicBrowserServiceFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/String;", "Landroid/os/Bundle;"),

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object PodCastConfigFingerprint : LiteralValueFingerprint(
internal object PodCastConfigFingerprint : LiteralValueFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -2,36 +2,17 @@ package app.revanced.patches.music.misc.minimizedplayback
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
@Patch(
@Suppress("unused")
object MinimizedPlaybackPatch : BaseBytecodePatch(
name = "Enable minimized playback",
description = "Enables playback in miniplayer for Kids music.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object MinimizedPlaybackPatch : BytecodePatch(
setOf(MinimizedPlaybackManagerFingerprint)
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(MinimizedPlaybackManagerFingerprint)
) {
override fun execute(context: BytecodeContext) {

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("I", "L", "Z"),

View File

@ -0,0 +1,90 @@
package app.revanced.patches.music.misc.premium
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patches.music.misc.premium.fingerprints.AccountMenuFooterFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsParentFingerprint
import app.revanced.patches.music.navigation.component.NavigationBarComponentPatch
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Suppress("unused")
object GetPremiumPatch : BaseBytecodePatch(
name = "Hide get premium",
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
dependencies = setOf(
NavigationBarComponentPatch::class,
SharedResourceIdPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
AccountMenuFooterFingerprint,
HideGetPremiumFingerprint,
MembershipSettingsParentFingerprint
)
) {
override fun execute(context: BytecodeContext) {
// Hides get premium button at the bottom of the account switching menu
HideGetPremiumFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.startIndex
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex + 1,
"const/4 v$register, 0x0"
)
}
} ?: throw HideGetPremiumFingerprint.exception
// Hides get premium button at the top of the account switching menu
AccountMenuFooterFingerprint.result?.let {
it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(PrivacyTosFooter)
val walkerIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL)
val viewIndex = getTargetIndex(constIndex, Opcode.IGET_OBJECT)
val viewReference = getInstruction<ReferenceInstruction>(viewIndex).reference.toString()
val walkerMethod = getWalkerMethod(context, walkerIndex)
walkerMethod.apply {
val insertIndex = getTargetIndexWithReference(viewReference)
val nullCheckIndex = getTargetIndex(insertIndex - 1, Opcode.IF_NEZ)
val nullCheckRegister = getInstruction<OneRegisterInstruction>(nullCheckIndex).registerA
addInstruction(
nullCheckIndex,
"const/4 v$nullCheckRegister, 0x0"
)
}
}
} ?: throw AccountMenuFooterFingerprint.exception
// Hides premium membership menu in settings
MembershipSettingsParentFingerprint.result?.classDef?.let { classDef ->
MembershipSettingsFingerprint.resolve(context, classDef)
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
0, """
const/4 v0, 0x0
return-object v0
"""
) ?: throw MembershipSettingsFingerprint.exception
} ?: throw MembershipSettingsParentFingerprint.exception
}
}

View File

@ -1,123 +0,0 @@
package app.revanced.patches.music.misc.premium
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.music.misc.premium.fingerprints.AccountMenuFooterFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsParentFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
import app.revanced.util.exception
import app.revanced.util.getWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference
@Patch(
name = "Hide get premium",
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
dependencies = [SharedResourceIdPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object HideGetPremiumPatch : BytecodePatch(
setOf(
AccountMenuFooterFingerprint,
HideGetPremiumFingerprint,
MembershipSettingsParentFingerprint
)
) {
override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.startIndex
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex + 1,
"const/4 v$register, 0x0"
)
}
} ?: throw HideGetPremiumFingerprint.exception
AccountMenuFooterFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(PrivacyTosFooter) + 4
targetReference = getInstruction<ReferenceInstruction>(targetIndex + 1).reference
with(
context
.toMethodWalker(this)
.nextMethod(targetIndex, true)
.getMethod() as MutableMethod
) {
this.implementation!!.instructions.apply {
for ((index, instruction) in withIndex()) {
if (instruction.opcode != Opcode.IGET_OBJECT) continue
if (getInstruction<ReferenceInstruction>(index).reference == targetReference) {
val targetRegister =
getInstruction<OneRegisterInstruction>(index + 2).registerA
addInstruction(
index,
"const/16 v$targetRegister, 0x8"
)
break
}
}
}
}
}
} ?: throw AccountMenuFooterFingerprint.exception
MembershipSettingsParentFingerprint.result?.let { parentResult ->
MembershipSettingsFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
}.result?.let {
it.mutableMethod.apply {
addInstructions(
0, """
const/4 v0, 0x0
return-object v0
"""
)
}
} ?: throw MembershipSettingsFingerprint.exception
} ?: throw MembershipSettingsParentFingerprint.exception
}
private lateinit var targetReference: Reference
}

View File

@ -6,7 +6,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object AccountMenuFooterFingerprint : LiteralValueFingerprint(
internal object AccountMenuFooterFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object HideGetPremiumFingerprint : MethodFingerprint(
internal object HideGetPremiumFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object MembershipSettingsFingerprint : MethodFingerprint(
internal object MembershipSettingsFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList()

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object MembershipSettingsParentFingerprint : MethodFingerprint(
internal object MembershipSettingsParentFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -0,0 +1,8 @@
package app.revanced.patches.music.misc.spoofappversion
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.shared.spoofappversion.BaseSpoofAppVersionPatch
object SpoofAppVersionBytecodePatch : BaseSpoofAppVersionPatch(
"$MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;"
)

View File

@ -1,49 +1,29 @@
package app.revanced.patches.music.misc.spoofappversion
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.utils.settings.SettingsPatch.contexts
import app.revanced.patches.shared.versionspoof.AbstractVersionSpoofPatch
import app.revanced.util.copyXmlNode
import app.revanced.util.patch.BaseResourcePatch
@Patch(
name = "Spoof app version",
description = "Adds options to spoof the YouTube Music client version. " +
"This can remove the radio mode restriction in Canadian regions or disable real-time lyrics.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object SpoofAppVersionPatch : AbstractVersionSpoofPatch(
"$MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;"
object SpoofAppVersionPatch : BaseResourcePatch(
name = "Spoof app version",
description = "Adds options to spoof the YouTube Music client version. " +
"This can remove the radio mode restriction in Canadian regions or disable real-time lyrics.",
dependencies = setOf(
SettingsPatch::class,
SpoofAppVersionBytecodePatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: BytecodeContext) {
super.execute(context)
override fun execute(context: ResourceContext) {
/**
* Copy arrays
*/
contexts.copyXmlNode("music/spoofappversion/host", "values/arrays.xml", "resources")
context.copyXmlNode("music/spoofappversion/host", "values/arrays.xml", "resources")
SettingsPatch.addMusicPreference(
CategoryType.MISC,

View File

@ -4,44 +4,25 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint
import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderSyntheticFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf
import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object TasteBuilderPatch : BaseBytecodePatch(
name = "Hide taste builder",
description = "Hides the \"Tell us which artists you like\" card from the homepage.",
dependencies = [SharedResourceIdPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object TasteBuilderPatch : BytecodePatch(
setOf(TasteBuilderConstructorFingerprint)
dependencies = setOf(SharedResourceIdPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TasteBuilderConstructorFingerprint)
) {
override fun execute(context: BytecodeContext) {
TasteBuilderConstructorFingerprint.result?.let { parentResult ->

View File

@ -5,7 +5,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTa
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object TasteBuilderConstructorFingerprint : LiteralValueFingerprint(
internal object TasteBuilderConstructorFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
literalSupplier = { MusicTasteBuilderShelf }

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object TasteBuilderSyntheticFingerprint : MethodFingerprint(
internal object TasteBuilderSyntheticFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
parameters = listOf("L", "Ljava/lang/Object;"),

View File

@ -0,0 +1,15 @@
package app.revanced.patches.music.misc.tracking
import app.revanced.patches.music.misc.tracking.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.shared.tracking.BaseSanitizeUrlQueryPatch
import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
object SanitizeUrlQueryBytecodePatch : BaseSanitizeUrlQueryPatch(
"$MISC_PATH/SanitizeUrlQueryPatch;",
listOf(
CopyTextEndpointFingerprint,
ShareLinkFormatterFingerprint
),
null
)

View File

@ -1,48 +1,22 @@
package app.revanced.patches.music.misc.tracking
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.misc.tracking.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.tracking.AbstractSanitizeUrlQueryPatch
import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object SanitizeUrlQueryPatch : BaseResourcePatch(
name = "Sanitize sharing links",
description = "Adds an option to remove tracking query parameters from URLs when sharing links.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object SanitizeUrlQueryPatch : AbstractSanitizeUrlQueryPatch(
"$MISC_PATH/SanitizeUrlQueryPatch;",
listOf(
CopyTextEndpointFingerprint,
ShareLinkFormatterFingerprint
dependencies = setOf(
SanitizeUrlQueryBytecodePatch::class,
SettingsPatch::class
),
null
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: BytecodeContext) {
super.execute(context)
override fun execute(context: ResourceContext) {
SettingsPatch.addMusicPreference(
CategoryType.MISC,

View File

@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
/**
* Sharing panel of YouTube Music
*/
object ShareLinkFormatterFingerprint : MethodFingerprint(
internal object ShareLinkFormatterFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L", "Ljava/util/Map;"),
opcodes = listOf(

View File

@ -1,56 +1,45 @@
package app.revanced.patches.music.misc.translations
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.translations.AbstractTranslationsPatch
import app.revanced.patches.shared.translations.TranslationsUtils.copyXml
import app.revanced.util.patch.BaseResourcePatch
@Patch(
@Suppress("unused")
object TranslationsPatch : BaseResourcePatch(
name = "Translations",
description = "Adds Crowdin translations for YouTube Music.",
dependencies = [SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE
) {
override fun execute(context: ResourceContext) {
context.copyXml(
"music",
arrayOf(
"bg-rBG",
"bn",
"cs-rCZ",
"el-rGR",
"es-rES",
"fr-rFR",
"id-rID",
"in",
"it-rIT",
"ja-rJP",
"ko-rKR",
"nl-rNL",
"pl-rPL",
"pt-rBR",
"ro-rRO",
"ru-rRU",
"tr-rTR",
"uk-rUA",
"vi-rVN",
"zh-rCN",
"zh-rTW"
)
)
]
)
@Suppress("unused")
object TranslationsPatch : AbstractTranslationsPatch(
"music",
arrayOf(
"bg-rBG",
"bn",
"cs-rCZ",
"el-rGR",
"es-rES",
"fr-rFR",
"id-rID",
"in",
"it-rIT",
"ja-rJP",
"ko-rKR",
"nl-rNL",
"pl-rPL",
"pt-rBR",
"ro-rRO",
"ru-rRU",
"tr-rTR",
"uk-rUA",
"vi-rVN",
"zh-rCN",
"zh-rTW"
)
)
}
}

View File

@ -3,45 +3,26 @@ package app.revanced.patches.music.navigation.black
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.navigation.black.fingerprints.TabLayoutFingerprint
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@Suppress("unused")
object BlackNavigationBarPatch : BaseBytecodePatch(
name = "Enable black navigation bar",
description = "Adds an option to set the navigation bar color to black.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object BlackNavigationBarPatch : BytecodePatch(
setOf(TabLayoutFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TabLayoutFingerprint)
) {
override fun execute(context: BytecodeContext) {
@ -52,7 +33,7 @@ object BlackNavigationBarPatch : BytecodePatch(
addInstructions(
targetIndex + 1, """
invoke-static {}, $NAVIGATION->enableBlackNavigationBar()I
invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I
move-result v$targetRegister
"""
)

View File

@ -6,7 +6,7 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object TabLayoutFingerprint : LiteralValueFingerprint(
internal object TabLayoutFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View File

@ -3,59 +3,45 @@ package app.revanced.patches.music.navigation.component
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.navigation.component.fingerprints.TabLayoutTextFingerprint
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION
import app.revanced.patches.music.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.patch.BaseBytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
@Suppress("DEPRECATION", "SpellCheckingInspection", "unused")
object NavigationBarComponentPatch : BaseBytecodePatch(
name = "Hide navigation bar component",
description = "Adds options to hide navigation bar components.",
dependencies = [
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music",
[
"6.21.52",
"6.22.52",
"6.23.56",
"6.25.53",
"6.26.51",
"6.27.54",
"6.28.53",
"6.29.58",
"6.31.55",
"6.33.52"
]
)
]
)
@Suppress("unused")
object NavigationBarComponentPatch : BytecodePatch(
setOf(TabLayoutTextFingerprint)
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(TabLayoutTextFingerprint)
) {
private const val FLAG = "android:layout_weight"
private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml"
override fun execute(context: BytecodeContext) {
/**
* Hide navigation labels
*/
TabLayoutTextFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.Text1) + 3
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.Text1)
val targetIndex = getTargetIndex(constIndex, Opcode.CHECK_CAST)
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
@ -64,7 +50,7 @@ object NavigationBarComponentPatch : BytecodePatch(
addInstruction(
targetIndex + 1,
"invoke-static {v$targetRegister}, $NAVIGATION->hideNavigationLabel(Landroid/widget/TextView;)V"
"invoke-static {v$targetRegister}, $NAVIGATION_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V"
)
}
} ?: throw TabLayoutTextFingerprint.exception
@ -89,24 +75,19 @@ object NavigationBarComponentPatch : BytecodePatch(
it.mutableMethod.apply {
val enumIndex = it.scanResult.patternScanResult!!.startIndex + 3
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
val insertEnumIndex = getTargetIndex(Opcode.AND_INT_LIT8) - 2
val insertIndex = implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.AND_INT_LIT8
} - 2
val pivotTabIndex = implementation!!.instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "getVisibility"
}
val pivotTabIndex = getTargetIndexWithMethodReferenceName("getVisibility")
val pivotTabRegister = getInstruction<Instruction35c>(pivotTabIndex).registerC
addInstruction(
pivotTabIndex,
"invoke-static {v$pivotTabRegister}, $NAVIGATION->hideNavigationButton(Landroid/view/View;)V"
"invoke-static {v$pivotTabRegister}, $NAVIGATION_CLASS_DESCRIPTOR->hideNavigationButton(Landroid/view/View;)V"
)
addInstruction(
insertIndex,
"sput-object v$enumRegister, $NAVIGATION->lastPivotTab:Ljava/lang/Enum;"
insertEnumIndex,
"sput-object v$enumRegister, $NAVIGATION_CLASS_DESCRIPTOR->lastPivotTab:Ljava/lang/Enum;"
)
}
} ?: throw TabLayoutTextFingerprint.exception
@ -147,7 +128,4 @@ object NavigationBarComponentPatch : BytecodePatch(
"true"
)
}
private const val FLAG = "android:layout_weight"
private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml"
}

Some files were not shown because too many files have changed in this diff Show More