mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-04 08:34:27 +02:00
refactor(YouTube Music/Settings): reorganize settings menu
This commit is contained in:
parent
1f59997e53
commit
01795e0fb4
@ -1,62 +0,0 @@
|
|||||||
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.patches.music.account.component.fingerprints.MenuEntryFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_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.getTargetIndexWithMethodReferenceName
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object MenuComponentPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide account menu",
|
|
||||||
description = "Adds the ability to hide account menu elements using a custom filter.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(MenuEntryFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
MenuEntryFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
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_CLASS_DESCRIPTOR->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACCOUNT,
|
|
||||||
"revanced_hide_account_menu",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addPreferenceWithIntent(
|
|
||||||
CategoryType.ACCOUNT,
|
|
||||||
"revanced_hide_account_menu_filter_strings",
|
|
||||||
"revanced_hide_account_menu"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACCOUNT,
|
|
||||||
"revanced_hide_account_menu_empty_component",
|
|
||||||
"false",
|
|
||||||
"revanced_hide_account_menu"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,145 @@
|
|||||||
|
package app.revanced.patches.music.account.components
|
||||||
|
|
||||||
|
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.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patches.music.account.components.fingerprints.AccountSwitcherAccessibilityLabelFingerprint
|
||||||
|
import app.revanced.patches.music.account.components.fingerprints.MenuEntryFingerprint
|
||||||
|
import app.revanced.patches.music.account.components.fingerprints.NamesInactiveAccountThumbnailSizeFingerprint
|
||||||
|
import app.revanced.patches.music.account.components.fingerprints.TermsOfServiceFingerprint
|
||||||
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_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.getTargetIndexWithMethodReferenceName
|
||||||
|
import app.revanced.util.getTargetIndexWithReference
|
||||||
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object AccountComponentsPatch : BaseBytecodePatch(
|
||||||
|
name = "Hide account components",
|
||||||
|
description = "Adds the options to hide components related to account menu.",
|
||||||
|
dependencies = setOf(
|
||||||
|
SettingsPatch::class,
|
||||||
|
SharedResourceIdPatch::class
|
||||||
|
),
|
||||||
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
|
fingerprints = setOf(
|
||||||
|
AccountSwitcherAccessibilityLabelFingerprint,
|
||||||
|
MenuEntryFingerprint,
|
||||||
|
NamesInactiveAccountThumbnailSizeFingerprint,
|
||||||
|
TermsOfServiceFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
|
// region patch for hide account menu
|
||||||
|
|
||||||
|
MenuEntryFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
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_CLASS_DESCRIPTOR->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide handle
|
||||||
|
|
||||||
|
// account menu
|
||||||
|
AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result ->
|
||||||
|
result.mutableMethod.apply {
|
||||||
|
|
||||||
|
val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor")
|
||||||
|
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility")
|
||||||
|
val textViewInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
setVisibilityIndex,
|
||||||
|
"invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Landroid/widget/TextView;I)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// account switcher
|
||||||
|
NamesInactiveAccountThumbnailSizeFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex, """
|
||||||
|
invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide terms container
|
||||||
|
|
||||||
|
TermsOfServiceFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V")
|
||||||
|
val visibilityRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex + 1,
|
||||||
|
"const/4 v$visibilityRegister, 0x0"
|
||||||
|
)
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {}, $ACCOUNT_CLASS_DESCRIPTOR->hideTermsContainer()I
|
||||||
|
move-result v$visibilityRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACCOUNT,
|
||||||
|
"revanced_hide_account_menu",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addPreferenceWithIntent(
|
||||||
|
CategoryType.ACCOUNT,
|
||||||
|
"revanced_hide_account_menu_filter_strings",
|
||||||
|
"revanced_hide_account_menu"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACCOUNT,
|
||||||
|
"revanced_hide_account_menu_empty_component",
|
||||||
|
"false",
|
||||||
|
"revanced_hide_account_menu"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACCOUNT,
|
||||||
|
"revanced_hide_handle",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACCOUNT,
|
||||||
|
"revanced_hide_terms_container",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.account.handle.fingerprints
|
package app.revanced.patches.music.account.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.account.component.fingerprints
|
package app.revanced.patches.music.account.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MenuEntry
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MenuEntry
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.account.handle.fingerprints
|
package app.revanced.patches.music.account.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.NamesInactiveAccountThumbnailSize
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.NamesInactiveAccountThumbnailSize
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.account.tos.fingerprints
|
package app.revanced.patches.music.account.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TosFooter
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TosFooter
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,77 +0,0 @@
|
|||||||
package app.revanced.patches.music.account.handle
|
|
||||||
|
|
||||||
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.patches.music.account.handle.fingerprints.AccountSwitcherAccessibilityLabelFingerprint
|
|
||||||
import app.revanced.patches.music.account.handle.fingerprints.NamesInactiveAccountThumbnailSizeFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_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.getTargetIndexWithMethodReferenceName
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object HandlePatch : BaseBytecodePatch(
|
|
||||||
name = "Hide handle",
|
|
||||||
description = "Adds an option to hide the handle in the account menu.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(
|
|
||||||
AccountSwitcherAccessibilityLabelFingerprint,
|
|
||||||
NamesInactiveAccountThumbnailSizeFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide handle in account menu
|
|
||||||
*/
|
|
||||||
AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result ->
|
|
||||||
result.mutableMethod.apply {
|
|
||||||
|
|
||||||
val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor")
|
|
||||||
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility")
|
|
||||||
val textViewInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
|
||||||
|
|
||||||
replaceInstruction(
|
|
||||||
setVisibilityIndex,
|
|
||||||
"invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Landroid/widget/TextView;I)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide handle in account switcher
|
|
||||||
*/
|
|
||||||
NamesInactiveAccountThumbnailSizeFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val targetIndex = it.scanResult.patternScanResult!!.startIndex
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
targetIndex, """
|
|
||||||
invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z
|
|
||||||
move-result v$targetRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACCOUNT,
|
|
||||||
"revanced_hide_handle",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package app.revanced.patches.music.account.tos
|
|
||||||
|
|
||||||
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.account.tos.fingerprints.TermsOfServiceFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_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.getTargetIndexWithReference
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(TermsOfServiceFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
TermsOfServiceFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V")
|
|
||||||
val visibilityRegister =
|
|
||||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex + 1,
|
|
||||||
"const/4 v$visibilityRegister, 0x0"
|
|
||||||
)
|
|
||||||
addInstructions(
|
|
||||||
insertIndex, """
|
|
||||||
invoke-static {}, $ACCOUNT_CLASS_DESCRIPTOR->hideTermsContainer()I
|
|
||||||
move-result v$visibilityRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACCOUNT,
|
|
||||||
"revanced_hide_terms_container",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.actionbar.component
|
package app.revanced.patches.music.actionbar.components
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
@ -6,8 +6,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.music.actionbar.component.fingerprints.ActionBarComponentFingerprint
|
import app.revanced.patches.music.actionbar.components.fingerprints.ActionBarComponentFingerprint
|
||||||
import app.revanced.patches.music.actionbar.component.fingerprints.LikeDislikeContainerFingerprint
|
import app.revanced.patches.music.actionbar.components.fingerprints.LikeDislikeContainerFingerprint
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ACTIONBAR_CLASS_DESCRIPTOR
|
import app.revanced.patches.music.utils.integrations.Constants.ACTIONBAR_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
||||||
@ -29,8 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ActionBarComponentPatch : BaseBytecodePatch(
|
object ActionBarComponentsPatch : BaseBytecodePatch(
|
||||||
name = "Hide action bar component",
|
name = "Hide action bar components",
|
||||||
description = "Adds options to hide action bar components and replace the offline download button with an external download button.",
|
description = "Adds options to hide action bar components and replace the offline download button with an external download button.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
@ -53,7 +53,7 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
addViewIndex + 1,
|
addViewIndex + 1,
|
||||||
"invoke-static {v$addViewRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->hookDownloadButton(Landroid/view/View;)V"
|
"invoke-static {v$addViewRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Landroid/view/View;)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
// hide action button label
|
// hide action button label
|
||||||
@ -132,7 +132,7 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ACTION_BAR,
|
CategoryType.ACTION_BAR,
|
||||||
"revanced_hide_action_button_add_to_playlist",
|
"revanced_hide_action_button_like_dislike",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
@ -140,26 +140,16 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
|||||||
"revanced_hide_action_button_comment",
|
"revanced_hide_action_button_comment",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACTION_BAR,
|
||||||
|
"revanced_hide_action_button_add_to_playlist",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ACTION_BAR,
|
CategoryType.ACTION_BAR,
|
||||||
"revanced_hide_action_button_download",
|
"revanced_hide_action_button_download",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACTION_BAR,
|
|
||||||
"revanced_hide_action_button_label",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACTION_BAR,
|
|
||||||
"revanced_hide_action_button_like_dislike",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.ACTION_BAR,
|
|
||||||
"revanced_hide_action_button_radio",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ACTION_BAR,
|
CategoryType.ACTION_BAR,
|
||||||
"revanced_hide_action_button_share",
|
"revanced_hide_action_button_share",
|
||||||
@ -167,13 +157,23 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
|||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ACTION_BAR,
|
CategoryType.ACTION_BAR,
|
||||||
"revanced_hook_action_button_download",
|
"revanced_hide_action_button_radio",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACTION_BAR,
|
||||||
|
"revanced_hide_action_button_label",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ACTION_BAR,
|
||||||
|
"revanced_external_downloader_action",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addPreferenceWithIntent(
|
SettingsPatch.addPreferenceWithIntent(
|
||||||
CategoryType.ACTION_BAR,
|
CategoryType.ACTION_BAR,
|
||||||
"revanced_external_downloader_package_name",
|
"revanced_external_downloader_package_name",
|
||||||
"revanced_hook_action_button_download"
|
"revanced_external_downloader_action"
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.actionbar.component.fingerprints
|
package app.revanced.patches.music.actionbar.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.actionbar.component.fingerprints
|
package app.revanced.patches.music.actionbar.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDislikeContainer
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDislikeContainer
|
@ -2,14 +2,19 @@ package app.revanced.patches.music.ads.general
|
|||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.music.ads.general.fingerprints.AccountMenuFooterFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint
|
||||||
|
import app.revanced.patches.music.ads.general.fingerprints.GetPremiumTextViewFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.InterstitialsContainerFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.InterstitialsContainerFingerprint
|
||||||
|
import app.revanced.patches.music.ads.general.fingerprints.MembershipSettingsFingerprint
|
||||||
|
import app.revanced.patches.music.ads.general.fingerprints.MembershipSettingsParentFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.NotifierShelfFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.NotifierShelfFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.ShowDialogCommandFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.ShowDialogCommandFingerprint
|
||||||
import app.revanced.patches.music.ads.music.MusicAdsPatch
|
import app.revanced.patches.music.navigation.components.NavigationBarComponentsPatch
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
|
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
||||||
@ -20,25 +25,35 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Interst
|
|||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
import app.revanced.patches.shared.litho.LithoFilterPatch
|
import app.revanced.patches.shared.litho.LithoFilterPatch
|
||||||
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexWithReference
|
||||||
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object GeneralAdsPatch : BaseBytecodePatch(
|
object AdsPatch : BaseBytecodePatch(
|
||||||
name = "Hide general ads",
|
name = "Hide ads",
|
||||||
description = "Adds options to hide general ads.",
|
description = "Adds options to hide ads.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
LithoFilterPatch::class,
|
LithoFilterPatch::class,
|
||||||
MusicAdsPatch::class,
|
MusicAdsPatch::class,
|
||||||
|
NavigationBarComponentsPatch::class, // for 'Hide upgrade button' setting
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
SharedResourceIdPatch::class
|
SharedResourceIdPatch::class
|
||||||
),
|
),
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
fingerprints = setOf(
|
fingerprints = setOf(
|
||||||
|
AccountMenuFooterFingerprint,
|
||||||
FloatingLayoutFingerprint,
|
FloatingLayoutFingerprint,
|
||||||
|
GetPremiumTextViewFingerprint,
|
||||||
InterstitialsContainerFingerprint,
|
InterstitialsContainerFingerprint,
|
||||||
|
MembershipSettingsParentFingerprint,
|
||||||
NotifierShelfFingerprint,
|
NotifierShelfFingerprint,
|
||||||
ShowDialogCommandFingerprint
|
ShowDialogCommandFingerprint
|
||||||
)
|
)
|
||||||
@ -58,10 +73,9 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
/**
|
// region patch for hide fullscreen ads
|
||||||
* Hides fullscreen ads
|
|
||||||
* Non-litho view, used in some old clients.
|
// non-litho view, used in some old clients
|
||||||
*/
|
|
||||||
InterstitialsContainerFingerprint.resultOrThrow().let {
|
InterstitialsContainerFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
|
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
|
||||||
@ -74,10 +88,7 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
||||||
* Hides fullscreen ads
|
|
||||||
* Litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
|
||||||
*/
|
|
||||||
ShowDialogCommandFingerprint.resultOrThrow().let {
|
ShowDialogCommandFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
// In this method, custom dialog is created and shown.
|
// In this method, custom dialog is created and shown.
|
||||||
@ -127,9 +138,10 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// endregion
|
||||||
* Hides premium promotion popup
|
|
||||||
*/
|
// region patch for hide premium promotion popup
|
||||||
|
|
||||||
FloatingLayoutFingerprint.resultOrThrow().let {
|
FloatingLayoutFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getWideLiteralInstructionIndex(FloatingLayout) + 2
|
val targetIndex = getWideLiteralInstructionIndex(FloatingLayout) + 2
|
||||||
@ -142,9 +154,10 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// endregion
|
||||||
* Hides premium renewal banner
|
|
||||||
*/
|
// region patch for hide premium renewal banner
|
||||||
|
|
||||||
NotifierShelfFingerprint.resultOrThrow().let {
|
NotifierShelfFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val linearLayoutIndex = getWideLiteralInstructionIndex(ButtonContainer) + 3
|
val linearLayoutIndex = getWideLiteralInstructionIndex(ButtonContainer) + 3
|
||||||
@ -158,6 +171,59 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide get premium
|
||||||
|
|
||||||
|
// get premium button at the top of the account switching menu
|
||||||
|
GetPremiumTextViewFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex + 1,
|
||||||
|
"const/4 v$register, 0x0"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get premium button at the bottom of the account switching menu
|
||||||
|
AccountMenuFooterFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.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"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// premium membership menu in settings
|
||||||
|
MembershipSettingsFingerprint.resolve(
|
||||||
|
context,
|
||||||
|
MembershipSettingsParentFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
MembershipSettingsFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
const/4 v0, 0x0
|
||||||
|
return-object v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ADS,
|
CategoryType.ADS,
|
||||||
"revanced_hide_fullscreen_ads",
|
"revanced_hide_fullscreen_ads",
|
||||||
@ -175,7 +241,7 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
|||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ADS,
|
CategoryType.ADS,
|
||||||
"revanced_hide_paid_promotion",
|
"revanced_hide_paid_promotion_label",
|
||||||
"true"
|
"true"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.ads.music
|
package app.revanced.patches.music.ads.general
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
|
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
|
||||||
import app.revanced.patches.shared.ads.BaseAdsPatch
|
import app.revanced.patches.shared.ads.BaseAdsPatch
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.premium.fingerprints
|
package app.revanced.patches.music.ads.general.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
|
@ -1,11 +1,11 @@
|
|||||||
package app.revanced.patches.music.misc.premium.fingerprints
|
package app.revanced.patches.music.ads.general.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object HideGetPremiumFingerprint : MethodFingerprint(
|
internal object GetPremiumTextViewFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.premium.fingerprints
|
package app.revanced.patches.music.ads.general.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.premium.fingerprints
|
package app.revanced.patches.music.ads.general.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -0,0 +1,420 @@
|
|||||||
|
package app.revanced.patches.music.flyoutmenu.components
|
||||||
|
|
||||||
|
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.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.DialogSolidFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.EndButtonsContainerFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.MenuItemFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.SleepTimerFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.TouchOutsideFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.TrimSilenceConfigFingerprint
|
||||||
|
import app.revanced.patches.music.flyoutmenu.components.fingerprints.TrimSilenceSwitchFingerprint
|
||||||
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
|
import app.revanced.patches.music.utils.flyoutmenu.FlyoutMenuHookPatch
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
||||||
|
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
|
||||||
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
|
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
|
||||||
|
import app.revanced.patches.music.video.information.VideoInformationPatch
|
||||||
|
import app.revanced.patches.shared.litho.LithoFilterPatch
|
||||||
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
|
import app.revanced.util.getWalkerMethod
|
||||||
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import app.revanced.util.literalInstructionBooleanHook
|
||||||
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
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
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object FlyoutMenuComponentsPatch : BaseBytecodePatch(
|
||||||
|
name = "Flyout menu components",
|
||||||
|
description = "Adds options to hide or change flyout menu components.",
|
||||||
|
dependencies = setOf(
|
||||||
|
FlyoutMenuComponentsResourcePatch::class,
|
||||||
|
FlyoutMenuHookPatch::class,
|
||||||
|
LithoFilterPatch::class,
|
||||||
|
SettingsPatch::class,
|
||||||
|
SharedResourceIdPatch::class,
|
||||||
|
VideoInformationPatch::class,
|
||||||
|
VideoTypeHookPatch::class
|
||||||
|
),
|
||||||
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
|
fingerprints = setOf(
|
||||||
|
DialogSolidFingerprint,
|
||||||
|
EndButtonsContainerFingerprint,
|
||||||
|
MenuItemFingerprint,
|
||||||
|
SleepTimerFingerprint,
|
||||||
|
TouchOutsideFingerprint,
|
||||||
|
TrimSilenceConfigFingerprint,
|
||||||
|
TrimSilenceSwitchFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
|
"$COMPONENTS_PATH/PlayerFlyoutMenuFilter;"
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
var trimSilenceIncluded = false
|
||||||
|
|
||||||
|
// region patch for enable compact dialog
|
||||||
|
|
||||||
|
DialogSolidFingerprint.resultOrThrow().let {
|
||||||
|
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||||
|
walkerMethod.addInstructions(
|
||||||
|
2, """
|
||||||
|
invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I
|
||||||
|
move-result p0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable trim silence
|
||||||
|
|
||||||
|
TrimSilenceConfigFingerprint.result?.let {
|
||||||
|
TrimSilenceConfigFingerprint.literalInstructionBooleanHook(
|
||||||
|
45619123,
|
||||||
|
"$FLYOUT_CLASS_DESCRIPTOR->enableTrimSilence(Z)Z"
|
||||||
|
)
|
||||||
|
|
||||||
|
TrimSilenceSwitchFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.TrimSilenceSwitch)
|
||||||
|
val onCheckedChangedListenerIndex = getTargetIndex(constIndex, Opcode.INVOKE_DIRECT)
|
||||||
|
val onCheckedChangedListenerReference = getInstruction<ReferenceInstruction>(onCheckedChangedListenerIndex).reference
|
||||||
|
val onCheckedChangedListenerDefiningClass = (onCheckedChangedListenerReference as MethodReference).definingClass
|
||||||
|
val onCheckedChangedListenerClass =
|
||||||
|
context.findClass(onCheckedChangedListenerDefiningClass)!!.mutableClass
|
||||||
|
|
||||||
|
onCheckedChangedListenerClass.methods.find { method -> method.name == "onCheckedChanged" }
|
||||||
|
?.apply {
|
||||||
|
val walkerIndex = indexOfFirstInstruction {
|
||||||
|
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
|
||||||
|
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL
|
||||||
|
&& reference?.returnType == "V"
|
||||||
|
&& reference.parameterTypes.size == 1
|
||||||
|
&& reference.parameterTypes[0] == "Z"
|
||||||
|
}
|
||||||
|
getWalkerMethod(context, walkerIndex).apply {
|
||||||
|
val insertIndex = getTargetIndex(Opcode.MOVE_RESULT)
|
||||||
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex + 1, """
|
||||||
|
invoke-static {v$insertRegister}, $FLYOUT_CLASS_DESCRIPTOR->enableTrimSilenceSwitch(Z)Z
|
||||||
|
move-result v$insertRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw PatchException("onClickClass not found!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trimSilenceIncluded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide flyout menu components and replace menu
|
||||||
|
|
||||||
|
MenuItemFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val freeIndex = getTargetIndex(Opcode.OR_INT_LIT16)
|
||||||
|
val textViewIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val imageViewIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
|
val freeRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(freeIndex).registerA
|
||||||
|
val textViewRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(textViewIndex).registerA
|
||||||
|
val imageViewRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(imageViewIndex).registerA
|
||||||
|
|
||||||
|
val enumIndex = indexOfFirstInstruction {
|
||||||
|
opcode == Opcode.INVOKE_STATIC
|
||||||
|
&& (this as? ReferenceInstruction)?.reference.toString().contains("(I)L")
|
||||||
|
} + 1
|
||||||
|
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
enumIndex + 1, """
|
||||||
|
invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V
|
||||||
|
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))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchOutsideFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener")
|
||||||
|
val setOnClickListenerRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
setOnClickListenerIndex + 1,
|
||||||
|
"invoke-static {v$setOnClickListenerRegister}, $FLYOUT_CLASS_DESCRIPTOR->setTouchOutSideView(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndButtonsContainerFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val startIndex = getWideLiteralInstructionIndex(EndButtonsContainer)
|
||||||
|
val targetIndex = getTargetIndex(startIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static {v$targetRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideLikeDislikeContainer(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable sleep timer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces sleep timer menu to be enabled.
|
||||||
|
* This method may be desperate in the future.
|
||||||
|
*/
|
||||||
|
SleepTimerFingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$targetRegister, 0x1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_enable_compact_dialog",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
if (trimSilenceIncluded) {
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_enable_trim_silence",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_like_dislike",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
if (SettingsPatch.upward0636) {
|
||||||
|
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_3_column_component",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_add_to_queue",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_captions",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_delete_playlist",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_dismiss_queue",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_download",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_edit_playlist",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_go_to_album",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_go_to_artist",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_go_to_episode",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_go_to_podcast",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_help",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_play_next",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_quality",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_remove_from_library",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_remove_from_playlist",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_report",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_save_episode_for_later",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_save_to_library",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_save_to_playlist",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_share",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_shuffle_play",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_sleep_timer",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_start_radio",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_stats_for_nerds",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_subscribe",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_hide_flyout_menu_view_song_credit",
|
||||||
|
"false",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_replace_flyout_menu_dismiss_queue",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_replace_flyout_menu_dismiss_queue_continue_watch",
|
||||||
|
"true",
|
||||||
|
"revanced_replace_flyout_menu_dismiss_queue"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_replace_flyout_menu_report",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.FLYOUT,
|
||||||
|
"revanced_replace_flyout_menu_report_only_player",
|
||||||
|
"true",
|
||||||
|
"revanced_replace_flyout_menu_report"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.replace
|
package app.revanced.patches.music.flyoutmenu.components
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.util.ResourceGroup
|
import app.revanced.util.ResourceGroup
|
||||||
import app.revanced.util.copyResources
|
import app.revanced.util.copyResources
|
||||||
|
|
||||||
object ReplaceReportResourcePatch : ResourcePatch() {
|
object FlyoutMenuComponentsResourcePatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
fun copyResources(resourceGroups: List<ResourceGroup>) {
|
fun copyResources(resourceGroups: List<ResourceGroup>) {
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.compactdialog.fingerprints
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DialogSolid
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DialogSolid
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.component.fingerprints
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.shared.fingerprints
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.component.fingerprints
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.replace.fingerprints
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TouchOutside
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TouchOutside
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
||||||
|
object TrimSilenceConfigFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
literalSupplier = { 45619123 }
|
||||||
|
)
|
@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.music.flyoutmenu.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TrimSilenceSwitch
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
object TrimSilenceSwitchFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Landroid/view/View;",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
literalSupplier = { TrimSilenceSwitch }
|
||||||
|
)
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.compactdialog
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patches.music.flyoutpanel.compactdialog.fingerprints.DialogSolidFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.getWalkerMethod
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object CompactDialogPatch : BaseBytecodePatch(
|
|
||||||
name = "Enable compact dialog",
|
|
||||||
description = "Adds an option to enable the compact flyout menu on phones.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(DialogSolidFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
DialogSolidFingerprint.resultOrThrow().let {
|
|
||||||
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
|
||||||
walkerMethod.addInstructions(
|
|
||||||
2, """
|
|
||||||
invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I
|
|
||||||
move-result p0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_enable_compact_dialog",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,248 +0,0 @@
|
|||||||
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.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.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
|
||||||
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
|
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
|
||||||
import app.revanced.patches.shared.litho.LithoFilterPatch
|
|
||||||
import app.revanced.util.getTargetIndex
|
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object FlyoutPanelPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide flyout panel",
|
|
||||||
description = "Adds options to hide flyout panel components.",
|
|
||||||
dependencies = setOf(
|
|
||||||
FlyoutPanelMenuItemPatch::class,
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(
|
|
||||||
EndButtonsContainerFingerprint,
|
|
||||||
SleepTimerFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/PlayerFlyoutPanelsFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
FlyoutPanelMenuItemPatch.hideComponents()
|
|
||||||
|
|
||||||
EndButtonsContainerFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val startIndex = getWideLiteralInstructionIndex(EndButtonsContainer)
|
|
||||||
val targetIndex = getTargetIndex(startIndex, Opcode.MOVE_RESULT_OBJECT)
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
targetIndex + 1,
|
|
||||||
"invoke-static {v$targetRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideLikeDislikeContainer(Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forces sleep timer menu to be enabled.
|
|
||||||
* This method may be desperate in the future.
|
|
||||||
*/
|
|
||||||
SleepTimerFingerprint.result?.let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex,
|
|
||||||
"const/4 v$targetRegister, 0x1"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SettingsPatch.upward0636) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_3_column_component",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_add_to_queue",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_captions",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_delete_playlist",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_dismiss_queue",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_download",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_edit_playlist",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_go_to_album",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_go_to_artist",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_go_to_episode",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_go_to_podcast",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_help",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_like_dislike",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_play_next",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_quality",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_remove_from_library",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_remove_from_playlist",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_report",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_save_episode_for_later",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_save_to_library",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_save_to_playlist",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_share",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_shuffle_play",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_sleep_timer",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_start_radio",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_stats_for_nerds",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_subscribe",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_hide_flyout_panel_view_song_credit",
|
|
||||||
"false",
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.replace
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
FlyoutPanelMenuItemPatch::class,
|
|
||||||
SettingsPatch::class,
|
|
||||||
VideoInformationPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
FlyoutPanelMenuItemPatch.replaceComponents()
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_replace_flyout_panel_dismiss_queue",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_replace_flyout_panel_dismiss_queue_continue_watch",
|
|
||||||
"true",
|
|
||||||
"revanced_replace_flyout_panel_dismiss_queue"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
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.patches.music.flyoutpanel.replace.fingerprints.TouchOutsideFingerprint
|
|
||||||
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch
|
|
||||||
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.patches.music.video.information.VideoInformationPatch
|
|
||||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object ReplaceReportPatch : BaseBytecodePatch(
|
|
||||||
name = "Replace report",
|
|
||||||
description = "Adds an option to replace \"Report\" with \"Playback speed\" in the flyout menu.",
|
|
||||||
dependencies = setOf(
|
|
||||||
FlyoutPanelMenuItemPatch::class,
|
|
||||||
PlaybackSpeedFlyoutPanelHookPatch::class,
|
|
||||||
ReplaceReportResourcePatch::class,
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class,
|
|
||||||
VideoInformationPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(TouchOutsideFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
FlyoutPanelMenuItemPatch.replaceComponents()
|
|
||||||
|
|
||||||
TouchOutsideFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener")
|
|
||||||
val setOnClickListenerRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
setOnClickListenerIndex + 1,
|
|
||||||
"sput-object v$setOnClickListenerRegister, $FLYOUT_CLASS_DESCRIPTOR->touchOutSideView:Landroid/view/View;"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_replace_flyout_panel_report",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.FLYOUT,
|
|
||||||
"revanced_replace_flyout_panel_report_only_player",
|
|
||||||
"true",
|
|
||||||
"revanced_replace_flyout_panel_report"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package app.revanced.patches.music.flyoutpanel.shared
|
|
||||||
|
|
||||||
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.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_CLASS_DESCRIPTOR
|
|
||||||
import app.revanced.util.getTargetIndex
|
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
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 kotlin.properties.Delegates
|
|
||||||
|
|
||||||
object FlyoutPanelMenuItemPatch : BytecodePatch(
|
|
||||||
setOf(MenuItemFingerprint)
|
|
||||||
) {
|
|
||||||
private lateinit var menuItemMethod: MutableMethod
|
|
||||||
private var freeRegister by Delegates.notNull<Int>()
|
|
||||||
private var textViewRegister by Delegates.notNull<Int>()
|
|
||||||
private var imageViewRegister by Delegates.notNull<Int>()
|
|
||||||
private var instructionAdded = false
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
MenuItemFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val freeIndex = getTargetIndex(Opcode.OR_INT_LIT16)
|
|
||||||
val textViewIndex = it.scanResult.patternScanResult!!.startIndex
|
|
||||||
val imageViewIndex = it.scanResult.patternScanResult!!.endIndex
|
|
||||||
|
|
||||||
freeRegister =
|
|
||||||
getInstruction<TwoRegisterInstruction>(freeIndex).registerA
|
|
||||||
textViewRegister =
|
|
||||||
getInstruction<OneRegisterInstruction>(textViewIndex).registerA
|
|
||||||
imageViewRegister =
|
|
||||||
getInstruction<OneRegisterInstruction>(imageViewIndex).registerA
|
|
||||||
|
|
||||||
menuItemMethod = this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableMethod.getEnumIndex() = indexOfFirstInstruction {
|
|
||||||
opcode == Opcode.INVOKE_STATIC
|
|
||||||
&& (this as? ReferenceInstruction)?.reference.toString().contains("(I)L")
|
|
||||||
} + 1
|
|
||||||
|
|
||||||
internal fun hideComponents() {
|
|
||||||
menuItemMethod.apply {
|
|
||||||
val enumIndex = getEnumIndex()
|
|
||||||
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
enumIndex + 1, """
|
|
||||||
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))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun replaceComponents() {
|
|
||||||
if (!instructionAdded) {
|
|
||||||
menuItemMethod.apply {
|
|
||||||
val enumIndex = getEnumIndex()
|
|
||||||
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
enumIndex + 1,
|
|
||||||
"invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
instructionAdded = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,7 @@ object AutoCaptionsPatch : BaseResourcePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
VideoIdPatch.hookBackgroundPlayVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
VideoIdPatch.hookVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.GENERAL,
|
CategoryType.GENERAL,
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.buttonshelf
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/ButtonShelfFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_button_shelf",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.carouselshelf
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/CarouselShelfFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_carousel_shelf",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.castbutton
|
|
||||||
|
|
||||||
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.PatchException
|
|
||||||
import app.revanced.patches.music.general.castbutton.fingerprints.MediaRouteButtonFingerprint
|
|
||||||
import app.revanced.patches.music.general.castbutton.fingerprints.PlayerOverlayChipFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.getWideLiteralInstructionIndex
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object CastButtonPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide cast button",
|
|
||||||
description = "Adds an option to hide the cast button.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(
|
|
||||||
MediaRouteButtonFingerprint,
|
|
||||||
PlayerOverlayChipFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide cast button
|
|
||||||
*/
|
|
||||||
MediaRouteButtonFingerprint.resultOrThrow().let {
|
|
||||||
val setVisibilityMethod =
|
|
||||||
it.mutableClass.methods.find { method -> method.name == "setVisibility" }
|
|
||||||
|
|
||||||
setVisibilityMethod?.apply {
|
|
||||||
addInstructions(
|
|
||||||
0, """
|
|
||||||
invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I
|
|
||||||
move-result p1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
} ?: throw PatchException("Failed to find setVisibility method")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide floating cast banner
|
|
||||||
*/
|
|
||||||
PlayerOverlayChipFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val targetIndex = getWideLiteralInstructionIndex(PlayerOverlayChip) + 2
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
targetIndex + 1,
|
|
||||||
"invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_cast_button",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
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.patches.music.general.categorybar.fingerprints.ChipCloudFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object CategoryBarPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide category bar",
|
|
||||||
description = "Adds an option to hide the category bar.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(ChipCloudFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
ChipCloudFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
targetIndex + 1,
|
|
||||||
"invoke-static { v$targetRegister }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBar(Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_category_bar",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.channelguidelines
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/ChannelGuidelinesFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_channel_guidelines",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,378 @@
|
|||||||
|
package app.revanced.patches.music.general.components
|
||||||
|
|
||||||
|
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.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.ChipCloudFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.ContentPillInFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.FloatingButtonFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.FloatingButtonParentFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.HistoryMenuItemFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.HistoryMenuItemOfflineTabFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.MediaRouteButtonFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.PlayerOverlayChipFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.SearchBarFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.SearchBarParentFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.SoundSearchFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.TasteBuilderConstructorFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.TasteBuilderSyntheticFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.TooltipContentViewFingerprint
|
||||||
|
import app.revanced.patches.music.general.components.fingerprints.TopBarMenuItemImageViewFingerprint
|
||||||
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
||||||
|
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.TopBarMenuItemImageView
|
||||||
|
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.patches.shared.voicesearch.VoiceSearchUtils.patchXml
|
||||||
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
|
import app.revanced.util.literalInstructionBooleanHook
|
||||||
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
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
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object LayoutComponentsPatch : BaseBytecodePatch(
|
||||||
|
name = "Hide layout components",
|
||||||
|
description = "Adds options to hide general layout components.",
|
||||||
|
dependencies = setOf(
|
||||||
|
LithoFilterPatch::class,
|
||||||
|
SharedResourceIdPatch::class,
|
||||||
|
SettingsPatch::class
|
||||||
|
),
|
||||||
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
|
fingerprints = setOf(
|
||||||
|
ChipCloudFingerprint,
|
||||||
|
ContentPillInFingerprint,
|
||||||
|
FloatingButtonParentFingerprint,
|
||||||
|
HistoryMenuItemFingerprint,
|
||||||
|
HistoryMenuItemOfflineTabFingerprint,
|
||||||
|
MediaRouteButtonFingerprint,
|
||||||
|
PlayerOverlayChipFingerprint,
|
||||||
|
SearchBarParentFingerprint,
|
||||||
|
SoundSearchFingerprint,
|
||||||
|
TasteBuilderConstructorFingerprint,
|
||||||
|
TooltipContentViewFingerprint,
|
||||||
|
TopBarMenuItemImageViewFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
private const val CUSTOM_FILTER_CLASS_DESCRIPTOR =
|
||||||
|
"$COMPONENTS_PATH/CustomFilter;"
|
||||||
|
|
||||||
|
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
|
||||||
|
"$COMPONENTS_PATH/LayoutComponentsFilter;"
|
||||||
|
|
||||||
|
private val ForceHideVoiceSearchButton by booleanPatchOption(
|
||||||
|
key = "ForceHideVoiceSearchButton",
|
||||||
|
default = false,
|
||||||
|
title = "Force hide voice search button",
|
||||||
|
description = "Hide voice search button with legacy method, button will always be hidden."
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
var notificationButtonIncluded = false
|
||||||
|
var soundSearchButtonIncluded = false
|
||||||
|
var voiceSearchButtonIncluded = false
|
||||||
|
|
||||||
|
// region patch for hide cast button
|
||||||
|
|
||||||
|
// hide cast button
|
||||||
|
MediaRouteButtonFingerprint.resultOrThrow().let {
|
||||||
|
val setVisibilityMethod =
|
||||||
|
it.mutableClass.methods.find { method -> method.name == "setVisibility" }
|
||||||
|
|
||||||
|
setVisibilityMethod?.apply {
|
||||||
|
addInstructions(
|
||||||
|
0, """
|
||||||
|
invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I
|
||||||
|
move-result p1
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} ?: throw PatchException("Failed to find setVisibility method")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide floating cast banner
|
||||||
|
PlayerOverlayChipFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.PlayerOverlayChip) + 2
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide category bar
|
||||||
|
|
||||||
|
ChipCloudFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static { v$targetRegister }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBar(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide floating button
|
||||||
|
|
||||||
|
FloatingButtonFingerprint.resolve(
|
||||||
|
context,
|
||||||
|
FloatingButtonParentFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
FloatingButtonFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
1, """
|
||||||
|
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingButton()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :show
|
||||||
|
return-void
|
||||||
|
""", ExternalLabel("show", getInstruction(1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide history button
|
||||||
|
|
||||||
|
arrayOf(
|
||||||
|
HistoryMenuItemFingerprint,
|
||||||
|
HistoryMenuItemOfflineTabFingerprint
|
||||||
|
).forEach { fingerprint ->
|
||||||
|
fingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHistoryButton(Z)Z
|
||||||
|
move-result v$insertRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide notification button
|
||||||
|
|
||||||
|
if (SettingsPatch.upward0642) {
|
||||||
|
TopBarMenuItemImageViewFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
val constIndex = getWideLiteralInstructionIndex(TopBarMenuItemImageView)
|
||||||
|
val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideNotificationButton(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
notificationButtonIncluded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide sound search button
|
||||||
|
|
||||||
|
SoundSearchFingerprint.result?.let {
|
||||||
|
SoundSearchFingerprint.literalInstructionBooleanHook(
|
||||||
|
45625491,
|
||||||
|
"$GENERAL_CLASS_DESCRIPTOR->hideSoundSearchButton(Z)Z"
|
||||||
|
)
|
||||||
|
soundSearchButtonIncluded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide tap to update button
|
||||||
|
|
||||||
|
ContentPillInFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideTapToUpdateButton()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :show
|
||||||
|
return-void
|
||||||
|
""", ExternalLabel("show", getInstruction(0))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide taste builder
|
||||||
|
|
||||||
|
TasteBuilderConstructorFingerprint.resultOrThrow().let { parentResult ->
|
||||||
|
TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
|
parentResult.mutableMethod.apply {
|
||||||
|
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.MusicTasteBuilderShelf)
|
||||||
|
val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideTasteBuilder(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TasteBuilderSyntheticFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$insertRegister, 0x0"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide tooltip content
|
||||||
|
|
||||||
|
TooltipContentViewFingerprint.resultOrThrow().mutableMethod.addInstruction(
|
||||||
|
0,
|
||||||
|
"return-void"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide voice search button
|
||||||
|
|
||||||
|
if (ForceHideVoiceSearchButton == true) {
|
||||||
|
SettingsPatch.contexts.patchXml(
|
||||||
|
arrayOf("search_toolbar_view.xml"),
|
||||||
|
arrayOf("height", "width")
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
SearchBarFingerprint.resolve(
|
||||||
|
context,
|
||||||
|
SearchBarParentFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
SearchBarFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val setVisibilityIndex = getTargetIndexWithMethodReferenceName("setVisibility")
|
||||||
|
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
setVisibilityIndex,
|
||||||
|
"invoke-static {v${setVisibilityInstruction.registerC}, v${setVisibilityInstruction.registerD}}, " +
|
||||||
|
"$GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/widget/ImageView;I)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
voiceSearchButtonIncluded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_custom_filter",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addPreferenceWithIntent(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_custom_filter_strings",
|
||||||
|
"revanced_custom_filter"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_button_shelf",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_carousel_shelf",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_playlist_card_shelf",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_samples_shelf",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_cast_button",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_category_bar",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_floating_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_tap_to_update_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_history_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
if (notificationButtonIncluded) {
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_notification_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (soundSearchButtonIncluded) {
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_sound_search_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (voiceSearchButtonIncluded) {
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.GENERAL,
|
||||||
|
"revanced_hide_voice_search_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.categorybar.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ChipCloud
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ChipCloud
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.taptoupdate.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.floatingbutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.floatingbutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.historybutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.historybutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.castbutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.castbutton.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip
|
@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||||
|
|
||||||
|
object SearchBarFingerprint : MethodReferenceNameFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
reference = { "setVisibility" }
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
|
||||||
|
object SearchBarParentFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Landroid/content/Intent;",
|
||||||
|
strings = listOf("web_search")
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
||||||
|
internal object SoundSearchFingerprint : LiteralValueFingerprint(
|
||||||
|
parameters = emptyList(),
|
||||||
|
literalSupplier = { 45625491 }
|
||||||
|
)
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.tastebuilder.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.tastebuilder.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.general.tooltip.fingerprints
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ToolTipContentView
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ToolTipContentView
|
@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.music.general.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopBarMenuItemImageView
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object TopBarMenuItemImageViewFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Landroid/view/View;",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = emptyList(),
|
||||||
|
literalSupplier = { TopBarMenuItemImageView }
|
||||||
|
)
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.customfilter
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object CustomFilterPatch : BaseResourcePatch(
|
|
||||||
name = "Enable custom filter",
|
|
||||||
description = "Adds a custom filter which can be used to hide layout components.",
|
|
||||||
dependencies = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/CustomFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_custom_filter",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addPreferenceWithIntent(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_custom_filter_strings",
|
|
||||||
"revanced_custom_filter"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.emojipicker
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@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 = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/EmojiPickerFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_emoji_picker",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
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.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.compatibility.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.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object FloatingButtonPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide new playlist button",
|
|
||||||
description = "Adds an option to hide the \"New playlist\" button in the library.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(FloatingButtonParentFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
FloatingButtonParentFingerprint.resultOrThrow().let { parentResult ->
|
|
||||||
FloatingButtonFingerprint.also {
|
|
||||||
it.resolve(
|
|
||||||
context,
|
|
||||||
parentResult.classDef
|
|
||||||
)
|
|
||||||
}.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
1, """
|
|
||||||
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideNewPlaylistButton()Z
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :show
|
|
||||||
return-void
|
|
||||||
""", ExternalLabel("show", getInstruction(1))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_new_playlist_button",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
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.patches.music.general.historybutton.fingerprints.HistoryMenuItemFingerprint
|
|
||||||
import app.revanced.patches.music.general.historybutton.fingerprints.HistoryMenuItemOfflineTabFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object HistoryButtonPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide history button",
|
|
||||||
description = "Adds an option to hide the history button in the toolbar.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(
|
|
||||||
HistoryMenuItemFingerprint,
|
|
||||||
HistoryMenuItemOfflineTabFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
arrayOf(
|
|
||||||
HistoryMenuItemFingerprint,
|
|
||||||
HistoryMenuItemOfflineTabFingerprint
|
|
||||||
).forEach { fingerprint ->
|
|
||||||
fingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
|
||||||
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
insertIndex, """
|
|
||||||
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHistoryButton(Z)Z
|
|
||||||
move-result v$insertRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_history_button",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
||||||
name = "Enable old style library shelf",
|
name = "Restore old style library shelf",
|
||||||
description = "Adds an option to return the library tab to the old style.",
|
description = "Adds an option to return the library tab to the old style.",
|
||||||
dependencies = setOf(SettingsPatch::class),
|
dependencies = setOf(SettingsPatch::class),
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
@ -33,7 +33,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
targetIndex + 1, """
|
targetIndex + 1, """
|
||||||
invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->enableOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String;
|
invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->restoreOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String;
|
||||||
move-result-object v$targetRegister
|
move-result-object v$targetRegister
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ -42,7 +42,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.GENERAL,
|
CategoryType.GENERAL,
|
||||||
"revanced_enable_old_style_library_shelf",
|
"revanced_restore_old_style_library_shelf",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.playlistcard
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object PlaylistCardPatch : BaseResourcePatch(
|
|
||||||
name = "Hide playlist card",
|
|
||||||
description = "Adds an option to hide the playlist card from the homepage.",
|
|
||||||
dependencies = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/PlaylistCardFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_playlist_card",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.sampleshelf
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object SampleShelfPatch : BaseResourcePatch(
|
|
||||||
name = "Hide sample shelf",
|
|
||||||
description = "Adds an option to hide the sample shelf from the homepage.",
|
|
||||||
dependencies = setOf(
|
|
||||||
LithoFilterPatch::class,
|
|
||||||
SettingsPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
|
||||||
) {
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
|
||||||
"$COMPONENTS_PATH/SampleShelfFilter;"
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_samples_shelf",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.music.general.spoofappversion
|
||||||
|
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||||
|
import app.revanced.patches.shared.spoofappversion.BaseSpoofAppVersionPatch
|
||||||
|
|
||||||
|
object SpoofAppVersionBytecodePatch : BaseSpoofAppVersionPatch(
|
||||||
|
"$GENERAL_CLASS_DESCRIPTOR->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;"
|
||||||
|
)
|
@ -1,10 +1,10 @@
|
|||||||
package app.revanced.patches.music.misc.spoofappversion
|
package app.revanced.patches.music.general.spoofappversion
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patches.music.general.oldstylelibraryshelf.OldStyleLibraryShelfPatch
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
import app.revanced.util.copyXmlNode
|
|
||||||
import app.revanced.util.patch.BaseResourcePatch
|
import app.revanced.util.patch.BaseResourcePatch
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@ -13,6 +13,7 @@ object SpoofAppVersionPatch : BaseResourcePatch(
|
|||||||
description = "Adds options to spoof the YouTube Music client 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.",
|
"This can remove the radio mode restriction in Canadian regions or disable real-time lyrics.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
|
OldStyleLibraryShelfPatch::class,
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
SpoofAppVersionBytecodePatch::class
|
SpoofAppVersionBytecodePatch::class
|
||||||
),
|
),
|
||||||
@ -20,18 +21,13 @@ object SpoofAppVersionPatch : BaseResourcePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy arrays
|
|
||||||
*/
|
|
||||||
context.copyXmlNode("music/spoofappversion/host", "values/arrays.xml", "resources")
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.MISC,
|
CategoryType.GENERAL,
|
||||||
"revanced_spoof_app_version",
|
"revanced_spoof_app_version",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addPreferenceWithIntent(
|
SettingsPatch.addPreferenceWithIntent(
|
||||||
CategoryType.MISC,
|
CategoryType.GENERAL,
|
||||||
"revanced_spoof_app_version_target",
|
"revanced_spoof_app_version_target",
|
||||||
"revanced_spoof_app_version"
|
"revanced_spoof_app_version"
|
||||||
)
|
)
|
@ -9,8 +9,6 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA
|
|||||||
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
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.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
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.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
@ -41,11 +39,6 @@ object ChangeStartPagePatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy arrays
|
|
||||||
*/
|
|
||||||
contexts.copyXmlNode("music/startpage/host", "values/arrays.xml", "resources")
|
|
||||||
|
|
||||||
SettingsPatch.addPreferenceWithIntent(
|
SettingsPatch.addPreferenceWithIntent(
|
||||||
CategoryType.GENERAL,
|
CategoryType.GENERAL,
|
||||||
"revanced_change_start_page"
|
"revanced_change_start_page"
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
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.util.smali.ExternalLabel
|
|
||||||
import app.revanced.patches.music.general.taptoupdate.fingerprints.ContentPillInFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object TapToUpdateButtonPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide tap to update button",
|
|
||||||
description = "Adds an option to hide the tap to update button.",
|
|
||||||
dependencies = setOf(SettingsPatch::class),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(ContentPillInFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
ContentPillInFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideTapToUpdateButton()Z
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :show
|
|
||||||
return-void
|
|
||||||
""", ExternalLabel("show", getInstruction(0))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.GENERAL,
|
|
||||||
"revanced_hide_tap_to_update_button",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.tooltip
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patches.music.general.tooltip.fingerprints.TooltipContentViewFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
|
|
||||||
@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 = setOf(SharedResourceIdPatch::class),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(TooltipContentViewFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
TooltipContentViewFingerprint.resultOrThrow().mutableMethod.addInstruction(
|
|
||||||
0,
|
|
||||||
"return-void"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package app.revanced.patches.music.general.voicesearch
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml
|
|
||||||
import app.revanced.util.patch.BaseResourcePatch
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object VoiceSearchButtonPatch : BaseResourcePatch(
|
|
||||||
name = "Hide voice search button",
|
|
||||||
description = "Hides the voice search button in the search bar.",
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
use = false
|
|
||||||
) {
|
|
||||||
override fun execute(context: ResourceContext) {
|
|
||||||
|
|
||||||
context.patchXml(
|
|
||||||
arrayOf("search_toolbar_view.xml"),
|
|
||||||
arrayOf("height", "width")
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import app.revanced.patcher.data.ResourceContext
|
|||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST
|
|
||||||
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
|
import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements
|
||||||
import app.revanced.util.patch.BaseResourcePatch
|
import app.revanced.util.patch.BaseResourcePatch
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
|||||||
|
|
||||||
private val AppNameNotification by stringPatchOption(
|
private val AppNameNotification by stringPatchOption(
|
||||||
key = "AppNameNotification",
|
key = "AppNameNotification",
|
||||||
default = APP_NAME_NOTIFICATION,
|
default = APP_NAME_LAUNCHER,
|
||||||
values = mapOf(
|
values = mapOf(
|
||||||
"Full name" to APP_NAME_NOTIFICATION,
|
"Full name" to APP_NAME_NOTIFICATION,
|
||||||
"Short name" to APP_NAME_LAUNCHER
|
"Short name" to APP_NAME_LAUNCHER
|
||||||
@ -44,7 +43,6 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
|||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
context.removeStringsElements(
|
context.removeStringsElements(
|
||||||
LANGUAGE_LIST,
|
|
||||||
arrayOf("app_launcher_name", "app_name")
|
arrayOf("app_launcher_name", "app_name")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package app.revanced.patches.music.misc.backgroundplay
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patches.music.misc.backgroundplay.fingerprints.BackgroundPlaybackFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object BackgroundPlayPatch : BaseBytecodePatch(
|
|
||||||
name = "Background play",
|
|
||||||
description = "Enables playing music in the background.",
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(BackgroundPlaybackFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
BackgroundPlaybackFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
addInstructions(
|
|
||||||
0, """
|
|
||||||
const/4 v0, 0x1
|
|
||||||
return v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ import app.revanced.util.patch.BaseResourcePatch
|
|||||||
@Suppress("DEPRECATION", "unused")
|
@Suppress("DEPRECATION", "unused")
|
||||||
object BitrateDefaultValuePatch : BaseResourcePatch(
|
object BitrateDefaultValuePatch : BaseResourcePatch(
|
||||||
name = "Bitrate default value",
|
name = "Bitrate default value",
|
||||||
description = "Sets the audio quality to \"Always High\" when you first install the app.",
|
description = "Sets the audio quality to 'Always High' when you first install the app.",
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
compatiblePackages = COMPATIBLE_PACKAGE
|
||||||
) {
|
) {
|
||||||
private const val RESOURCE_FILE_PATH = "res/xml/data_saving_settings.xml"
|
private const val RESOURCE_FILE_PATH = "res/xml/data_saving_settings.xml"
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
package app.revanced.patches.music.misc.exclusiveaudio
|
|
||||||
|
|
||||||
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.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.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.util.getStringInstructionIndex
|
|
||||||
import app.revanced.util.getWalkerMethod
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
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
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object ExclusiveAudioPatch : BaseBytecodePatch(
|
|
||||||
name = "Exclusive audio playback",
|
|
||||||
description = "Unlocks the option to play music without video.",
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(
|
|
||||||
DataSavingSettingsFragmentFingerprint,
|
|
||||||
MusicBrowserServiceFingerprint,
|
|
||||||
PodCastConfigFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't play music videos
|
|
||||||
*/
|
|
||||||
MusicBrowserServiceFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val targetIndex =
|
|
||||||
getStringInstructionIndex("MBS: Return empty root for client: %s, isFullMediaBrowserEnabled: %b, is client browsable: %b, isRedAccount: %b")
|
|
||||||
|
|
||||||
for (index in targetIndex downTo 0) {
|
|
||||||
if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue
|
|
||||||
|
|
||||||
val targetReference = getInstruction<ReferenceInstruction>(index).reference
|
|
||||||
|
|
||||||
if (!targetReference.toString().endsWith("()Z")) continue
|
|
||||||
|
|
||||||
val walkerMethod = getWalkerMethod(context, index)
|
|
||||||
|
|
||||||
walkerMethod.addInstructions(
|
|
||||||
0, """
|
|
||||||
const/4 v0, 0x1
|
|
||||||
return v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't play podcast videos
|
|
||||||
*/
|
|
||||||
PodCastConfigFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex,
|
|
||||||
"const/4 v$targetRegister, 0x1"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSavingSettingsFragmentFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = getStringInstructionIndex("pref_key_dont_play_nma_video") + 4
|
|
||||||
val targetRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex,
|
|
||||||
"const/4 v$targetRegister, 0x1"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,23 +2,112 @@ package app.revanced.patches.music.misc.minimizedplayback
|
|||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
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.minimizedplayback.fingerprints.BackgroundPlaybackFingerprint
|
||||||
|
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.DataSavingSettingsFragmentFingerprint
|
||||||
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
||||||
|
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MusicBrowserServiceFingerprint
|
||||||
|
import app.revanced.patches.music.misc.minimizedplayback.fingerprints.PodCastConfigFingerprint
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
|
import app.revanced.util.getStringInstructionIndex
|
||||||
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
|
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
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object MinimizedPlaybackPatch : BaseBytecodePatch(
|
object MinimizedPlaybackPatch : BaseBytecodePatch(
|
||||||
name = "Enable minimized playback",
|
name = "Enable minimized playback",
|
||||||
description = "Enables playback in miniplayer for Kids music.",
|
description = "Enables minimized and background playback.",
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
fingerprints = setOf(MinimizedPlaybackManagerFingerprint)
|
fingerprints = setOf(
|
||||||
|
BackgroundPlaybackFingerprint,
|
||||||
|
DataSavingSettingsFragmentFingerprint,
|
||||||
|
MinimizedPlaybackManagerFingerprint,
|
||||||
|
MusicBrowserServiceFingerprint,
|
||||||
|
PodCastConfigFingerprint,
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
|
// region patch for background play
|
||||||
|
|
||||||
|
BackgroundPlaybackFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for exclusive audio playback
|
||||||
|
|
||||||
|
// don't play music video
|
||||||
|
MusicBrowserServiceFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex =
|
||||||
|
getStringInstructionIndex("MBS: Return empty root for client: %s, isFullMediaBrowserEnabled: %b, is client browsable: %b, isRedAccount: %b")
|
||||||
|
|
||||||
|
for (index in targetIndex downTo 0) {
|
||||||
|
if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue
|
||||||
|
|
||||||
|
val targetReference = getInstruction<ReferenceInstruction>(index).reference
|
||||||
|
|
||||||
|
if (!targetReference.toString().endsWith("()Z")) continue
|
||||||
|
|
||||||
|
val walkerMethod = getWalkerMethod(context, index)
|
||||||
|
|
||||||
|
walkerMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't play podcast videos
|
||||||
|
PodCastConfigFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$targetRegister, 0x1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't play podcast videos
|
||||||
|
DataSavingSettingsFragmentFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = getStringInstructionIndex("pref_key_dont_play_nma_video") + 4
|
||||||
|
val targetRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"const/4 v$targetRegister, 0x1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for minimized playback
|
||||||
|
|
||||||
MinimizedPlaybackManagerFingerprint.resultOrThrow().mutableMethod.addInstruction(
|
MinimizedPlaybackManagerFingerprint.resultOrThrow().mutableMethod.addInstruction(
|
||||||
0, "return-void"
|
0, "return-void"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.backgroundplay.fingerprints
|
package app.revanced.patches.music.misc.minimizedplayback.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.exclusiveaudio.fingerprints
|
package app.revanced.patches.music.misc.minimizedplayback.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.exclusiveaudio.fingerprints
|
package app.revanced.patches.music.misc.minimizedplayback.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.misc.exclusiveaudio.fingerprints
|
package app.revanced.patches.music.misc.minimizedplayback.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,90 +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.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.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
|
|
||||||
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 app.revanced.util.resultOrThrow
|
|
||||||
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.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
|
||||||
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex + 1,
|
|
||||||
"const/4 v$register, 0x0"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hides get premium button at the top of the account switching menu
|
|
||||||
AccountMenuFooterFingerprint.resultOrThrow().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"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hides premium membership menu in settings
|
|
||||||
MembershipSettingsParentFingerprint.resultOrThrow().classDef.let { classDef ->
|
|
||||||
MembershipSettingsFingerprint.resolve(context, classDef)
|
|
||||||
MembershipSettingsFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
|
||||||
0, """
|
|
||||||
const/4 v0, 0x0
|
|
||||||
return-object v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
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;"
|
|
||||||
)
|
|
@ -1,58 +0,0 @@
|
|||||||
package app.revanced.patches.music.misc.tastebuilder
|
|
||||||
|
|
||||||
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.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint
|
|
||||||
import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderSyntheticFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf
|
|
||||||
import app.revanced.util.getTargetIndex
|
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object TasteBuilderPatch : BaseBytecodePatch(
|
|
||||||
name = "Hide taste builder",
|
|
||||||
description = "Hides the \"Tell us which artists you like\" card from the homepage.",
|
|
||||||
dependencies = setOf(SharedResourceIdPatch::class),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(TasteBuilderConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
TasteBuilderConstructorFingerprint.resultOrThrow().let { parentResult ->
|
|
||||||
TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef)
|
|
||||||
|
|
||||||
parentResult.mutableMethod.apply {
|
|
||||||
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
|
||||||
val constIndex = getWideLiteralInstructionIndex(MusicTasteBuilderShelf)
|
|
||||||
val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
targetIndex + 1, """
|
|
||||||
const/16 v$freeRegister, 0x8
|
|
||||||
invoke-virtual {v$targetRegister, v$freeRegister}, Landroid/view/View;->setVisibility(I)V
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TasteBuilderSyntheticFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
insertIndex,
|
|
||||||
"const/4 v$insertRegister, 0x0"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
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.patches.music.navigation.black.fingerprints.TabLayoutFingerprint
|
|
||||||
import app.revanced.patches.music.utils.compatibility.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.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object BlackNavigationBarPatch : BaseBytecodePatch(
|
|
||||||
name = "Enable black navigation bar",
|
|
||||||
description = "Adds an option to set the navigation bar color to black.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(TabLayoutFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
TabLayoutFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
targetIndex + 1, """
|
|
||||||
invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I
|
|
||||||
move-result v$targetRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.NAVIGATION,
|
|
||||||
"revanced_enable_black_navigation_bar",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,12 @@
|
|||||||
package app.revanced.patches.music.navigation.component
|
package app.revanced.patches.music.navigation.components
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
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.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patches.music.navigation.component.fingerprints.TabLayoutTextFingerprint
|
import app.revanced.patches.music.navigation.components.fingerprints.TabLayoutFingerprint
|
||||||
|
import app.revanced.patches.music.navigation.components.fingerprints.TabLayoutTextFingerprint
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
|
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.resourceid.SharedResourceIdPatch
|
||||||
@ -21,20 +23,41 @@ 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.instruction.formats.Instruction35c
|
||||||
|
|
||||||
@Suppress("DEPRECATION", "SpellCheckingInspection", "unused")
|
@Suppress("DEPRECATION", "SpellCheckingInspection", "unused")
|
||||||
object NavigationBarComponentPatch : BaseBytecodePatch(
|
object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||||
name = "Hide navigation bar component",
|
name = "Navigation bar components",
|
||||||
description = "Adds options to hide navigation bar components.",
|
description = "Adds options to hide or change components related to navigation bar.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
SharedResourceIdPatch::class
|
SharedResourceIdPatch::class
|
||||||
),
|
),
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
fingerprints = setOf(TabLayoutTextFingerprint)
|
fingerprints = setOf(
|
||||||
|
TabLayoutFingerprint,
|
||||||
|
TabLayoutTextFingerprint
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
private const val FLAG = "android:layout_weight"
|
private const val FLAG = "android:layout_weight"
|
||||||
private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml"
|
private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable black navigation bar
|
||||||
|
*/
|
||||||
|
TabLayoutFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex + 1, """
|
||||||
|
invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide navigation labels
|
* Hide navigation labels
|
||||||
*/
|
*/
|
||||||
@ -94,19 +117,34 @@ object NavigationBarComponentPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.NAVIGATION,
|
CategoryType.NAVIGATION,
|
||||||
"revanced_hide_explore_button",
|
"revanced_enable_black_navigation_bar",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.NAVIGATION,
|
||||||
|
"revanced_hide_navigation_home_button",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.NAVIGATION,
|
CategoryType.NAVIGATION,
|
||||||
"revanced_hide_home_button",
|
"revanced_hide_navigation_samples_button",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.NAVIGATION,
|
CategoryType.NAVIGATION,
|
||||||
"revanced_hide_library_button",
|
"revanced_hide_navigation_explore_button",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.NAVIGATION,
|
||||||
|
"revanced_hide_navigation_library_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.NAVIGATION,
|
||||||
|
"revanced_hide_navigation_upgrade_button",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.NAVIGATION,
|
CategoryType.NAVIGATION,
|
||||||
"revanced_hide_navigation_bar",
|
"revanced_hide_navigation_bar",
|
||||||
@ -117,15 +155,5 @@ object NavigationBarComponentPatch : BaseBytecodePatch(
|
|||||||
"revanced_hide_navigation_label",
|
"revanced_hide_navigation_label",
|
||||||
"false"
|
"false"
|
||||||
)
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.NAVIGATION,
|
|
||||||
"revanced_hide_samples_button",
|
|
||||||
"false"
|
|
||||||
)
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.NAVIGATION,
|
|
||||||
"revanced_hide_upgrade_button",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.navigation.black.fingerprints
|
package app.revanced.patches.music.navigation.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.navigation.component.fingerprints
|
package app.revanced.patches.music.navigation.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Text1
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Text1
|
@ -1,107 +0,0 @@
|
|||||||
package app.revanced.patches.music.player.colormatchplayer
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
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.extensions.or
|
|
||||||
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
|
||||||
import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint
|
|
||||||
import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint
|
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
|
||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
|
||||||
import app.revanced.util.getTargetIndex
|
|
||||||
import app.revanced.util.getTargetIndexReversed
|
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
|
||||||
import app.revanced.util.resultOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.MethodParameter
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
object ColorMatchPlayerPatch : BaseBytecodePatch(
|
|
||||||
name = "Enable color match player",
|
|
||||||
description = "Adds an option to match the color of the miniplayer to the fullscreen player.",
|
|
||||||
dependencies = setOf(
|
|
||||||
SettingsPatch::class,
|
|
||||||
SharedResourceIdPatch::class
|
|
||||||
),
|
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
|
||||||
fingerprints = setOf(MiniPlayerConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
private lateinit var invokeVirtualReference: Reference
|
|
||||||
private lateinit var iGetReference: Reference
|
|
||||||
private lateinit var iPutReference: Reference
|
|
||||||
private lateinit var methodParameter: List<MethodParameter>
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
|
|
||||||
MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult ->
|
|
||||||
// Resolves fingerprints
|
|
||||||
SwitchToggleColorFingerprint.resolve(context, parentResult.classDef)
|
|
||||||
|
|
||||||
SwitchToggleColorFingerprint.resultOrThrow().let {
|
|
||||||
it.mutableMethod.apply {
|
|
||||||
methodParameter = parameters
|
|
||||||
|
|
||||||
val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
|
||||||
val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL)
|
|
||||||
val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET)
|
|
||||||
|
|
||||||
invokeVirtualReference = getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference
|
|
||||||
iGetReference = getInstruction<ReferenceInstruction>(iGetIndex).reference
|
|
||||||
}
|
|
||||||
|
|
||||||
parentResult.mutableMethod.apply {
|
|
||||||
val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey)
|
|
||||||
val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT)
|
|
||||||
|
|
||||||
iPutReference = getInstruction<ReferenceInstruction>(iPutIndex).reference
|
|
||||||
}
|
|
||||||
|
|
||||||
parentResult.mutableClass.methods.filter { method ->
|
|
||||||
method.accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL
|
|
||||||
&& method.parameters == methodParameter
|
|
||||||
&& method.returnType == "V"
|
|
||||||
}.forEach { mutableMethod ->
|
|
||||||
mutableMethod.apply {
|
|
||||||
val freeRegister = implementation!!.registerCount - parameters.size - 3
|
|
||||||
|
|
||||||
val invokeDirectIndex = getTargetIndexReversed(implementation!!.instructions.size - 1, Opcode.INVOKE_DIRECT)
|
|
||||||
val invokeDirectReference = getInstruction<ReferenceInstruction>(invokeDirectIndex).reference
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
invokeDirectIndex + 1, """
|
|
||||||
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableColorMatchPlayer()Z
|
|
||||||
move-result v$freeRegister
|
|
||||||
if-eqz v$freeRegister, :off
|
|
||||||
invoke-virtual {p1}, $invokeVirtualReference
|
|
||||||
move-result-object v$freeRegister
|
|
||||||
check-cast v$freeRegister, ${(iGetReference as FieldReference).definingClass}
|
|
||||||
iget v$freeRegister, v$freeRegister, $iGetReference
|
|
||||||
iput v$freeRegister, p0, $iPutReference
|
|
||||||
:off
|
|
||||||
invoke-direct {p0}, $invokeDirectReference
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
removeInstruction(invokeDirectIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
|
||||||
CategoryType.PLAYER,
|
|
||||||
"revanced_enable_color_match_player",
|
|
||||||
"true"
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,836 @@
|
|||||||
|
package app.revanced.patches.music.player.components
|
||||||
|
|
||||||
|
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.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.HandleSearchRenderedFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.HandleSignInEventFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.InteractionLoggingEnumFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MiniPlayerConstructorFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MiniPlayerDefaultTextFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MiniPlayerDefaultViewVisibilityFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MiniPlayerParentFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MinimizedPlayerFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MppWatchWhileLayoutFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MusicActivityWidgetFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MusicPlaybackControlsFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.NextButtonVisibilityFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.OldEngagementPanelFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.OldPlayerBackgroundFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.OldPlayerLayoutFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.PlayerPatchConstructorFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.RemixGenericButtonFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.RepeatTrackFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.SwipeToCloseFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.SwitchToggleColorFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.ZenModeFingerprint
|
||||||
|
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
|
import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFingerprint
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopEnd
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopStart
|
||||||
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
|
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
|
||||||
|
import app.revanced.patches.shared.litho.LithoFilterPatch
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.getStringInstructionIndex
|
||||||
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexReversed
|
||||||
|
import app.revanced.util.getTargetIndexWithFieldReferenceType
|
||||||
|
import app.revanced.util.getWalkerMethod
|
||||||
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
|
import app.revanced.util.literalInstructionBooleanHook
|
||||||
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
import app.revanced.util.transformFields
|
||||||
|
import app.revanced.util.traverseClassHierarchy
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
|
import com.android.tools.smali.dexlib2.iface.MethodParameter
|
||||||
|
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.FieldReference
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
@Suppress("unused", "LocalVariableName")
|
||||||
|
object PlayerComponentsPatch : BaseBytecodePatch(
|
||||||
|
name = "Player components",
|
||||||
|
description = "Adds options to hide or change components related to player.",
|
||||||
|
dependencies = setOf(
|
||||||
|
LithoFilterPatch::class,
|
||||||
|
PlayerComponentsResourcePatch::class,
|
||||||
|
SettingsPatch::class,
|
||||||
|
SharedResourceIdPatch::class,
|
||||||
|
VideoTypeHookPatch::class
|
||||||
|
),
|
||||||
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
|
fingerprints = setOf(
|
||||||
|
HandleSearchRenderedFingerprint,
|
||||||
|
InteractionLoggingEnumFingerprint,
|
||||||
|
MinimizedPlayerFingerprint,
|
||||||
|
MiniPlayerConstructorFingerprint,
|
||||||
|
MiniPlayerDefaultTextFingerprint,
|
||||||
|
MiniPlayerDefaultViewVisibilityFingerprint,
|
||||||
|
MiniPlayerParentFingerprint,
|
||||||
|
MppWatchWhileLayoutFingerprint,
|
||||||
|
MusicActivityWidgetFingerprint,
|
||||||
|
MusicPlaybackControlsFingerprint,
|
||||||
|
OldEngagementPanelFingerprint,
|
||||||
|
OldPlayerBackgroundFingerprint,
|
||||||
|
OldPlayerLayoutFingerprint,
|
||||||
|
PendingIntentReceiverFingerprint,
|
||||||
|
PlayerPatchConstructorFingerprint,
|
||||||
|
RemixGenericButtonFingerprint,
|
||||||
|
RepeatTrackFingerprint,
|
||||||
|
ShuffleClassReferenceFingerprint,
|
||||||
|
SwipeToCloseFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
|
"$COMPONENTS_PATH/PlayerComponentsFilter;"
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
|
// region patch for enable color match player
|
||||||
|
|
||||||
|
lateinit var colorMathPlayerInvokeVirtualReference: Reference
|
||||||
|
lateinit var colorMathPlayerIGetReference: Reference
|
||||||
|
lateinit var colorMathPlayerIPutReference: Reference
|
||||||
|
lateinit var colorMathPlayerMethodParameter: List<MethodParameter>
|
||||||
|
|
||||||
|
MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult ->
|
||||||
|
// Resolves fingerprints
|
||||||
|
SwitchToggleColorFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
|
SwitchToggleColorFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
colorMathPlayerMethodParameter = parameters
|
||||||
|
|
||||||
|
val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||||
|
val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET)
|
||||||
|
|
||||||
|
colorMathPlayerInvokeVirtualReference = getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference
|
||||||
|
colorMathPlayerIGetReference = getInstruction<ReferenceInstruction>(iGetIndex).reference
|
||||||
|
}
|
||||||
|
|
||||||
|
parentResult.mutableMethod.apply {
|
||||||
|
val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey)
|
||||||
|
val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT)
|
||||||
|
|
||||||
|
colorMathPlayerIPutReference = getInstruction<ReferenceInstruction>(iPutIndex).reference
|
||||||
|
}
|
||||||
|
|
||||||
|
parentResult.mutableClass.methods.filter { method ->
|
||||||
|
method.accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL
|
||||||
|
&& method.parameters == colorMathPlayerMethodParameter
|
||||||
|
&& method.returnType == "V"
|
||||||
|
}.forEach { mutableMethod ->
|
||||||
|
mutableMethod.apply {
|
||||||
|
val freeRegister = implementation!!.registerCount - parameters.size - 3
|
||||||
|
|
||||||
|
val invokeDirectIndex = getTargetIndexReversed(implementation!!.instructions.size - 1, Opcode.INVOKE_DIRECT)
|
||||||
|
val invokeDirectReference = getInstruction<ReferenceInstruction>(invokeDirectIndex).reference
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
invokeDirectIndex + 1, """
|
||||||
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableColorMatchPlayer()Z
|
||||||
|
move-result v$freeRegister
|
||||||
|
if-eqz v$freeRegister, :off
|
||||||
|
invoke-virtual {p1}, $colorMathPlayerInvokeVirtualReference
|
||||||
|
move-result-object v$freeRegister
|
||||||
|
check-cast v$freeRegister, ${(colorMathPlayerIGetReference as FieldReference).definingClass}
|
||||||
|
iget v$freeRegister, v$freeRegister, $colorMathPlayerIGetReference
|
||||||
|
iput v$freeRegister, p0, $colorMathPlayerIPutReference
|
||||||
|
:off
|
||||||
|
invoke-direct {p0}, $invokeDirectReference
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
removeInstruction(invokeDirectIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_color_match_player",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable force minimized player
|
||||||
|
|
||||||
|
MinimizedPlayerFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableForceMinimizedPlayer(Z)Z
|
||||||
|
move-result v$insertRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_force_minimized_player",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable next previous button
|
||||||
|
|
||||||
|
val NEXT_BUTTON_FIELD_NAME = "nextButton"
|
||||||
|
val PREVIOUS_BUTTON_FIELD_NAME = "previousButton"
|
||||||
|
val NEXT_BUTTON_CLASS_FIELD_NAME = "nextButtonClass"
|
||||||
|
val PREVIOUS_BUTTON_CLASS_FIELD_NAME = "previousButtonClass"
|
||||||
|
val NEXT_BUTTON_METHOD_NAME = "setNextButton"
|
||||||
|
val PREVIOUS_BUTTON_METHOD_NAME = "setPreviousButton"
|
||||||
|
val NEXT_BUTTON_ONCLICK_METHOD_NAME = "setNextButtonOnClickListener"
|
||||||
|
val PREVIOUS_BUTTON_ONCLICK_METHOD_NAME = "setPreviousButtonOnClickListener"
|
||||||
|
val NEXT_BUTTON_INTENT_STRING = "YTM Next"
|
||||||
|
val PREVIOUS_BUTTON_INTENT_STRING = "YTM Previous"
|
||||||
|
|
||||||
|
val miniPlayerConstructorMutableMethod =
|
||||||
|
MiniPlayerConstructorFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
|
val mppWatchWhileLayoutMutableMethod =
|
||||||
|
MppWatchWhileLayoutFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
|
val pendingIntentReceiverMutableMethod =
|
||||||
|
PendingIntentReceiverFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
|
if (!SettingsPatch.upward0642) {
|
||||||
|
MiniPlayerParentFingerprint.resultOrThrow().let { parentResult ->
|
||||||
|
// Resolves fingerprints
|
||||||
|
NextButtonVisibilityFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
|
NextButtonVisibilityFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||||
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex + 1, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableMiniPlayerNextButton(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart)
|
||||||
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart)
|
||||||
|
pendingIntentReceiverMutableMethod.setOnClickListener(context, NEXT_BUTTON_INTENT_STRING, NEXT_BUTTON_ONCLICK_METHOD_NAME, NEXT_BUTTON_CLASS_FIELD_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd)
|
||||||
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd)
|
||||||
|
pendingIntentReceiverMutableMethod.setOnClickListener(context, PREVIOUS_BUTTON_INTENT_STRING, PREVIOUS_BUTTON_ONCLICK_METHOD_NAME, PREVIOUS_BUTTON_CLASS_FIELD_NAME)
|
||||||
|
|
||||||
|
mppWatchWhileLayoutMutableMethod.setViewArray()
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_mini_player_next_button",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_mini_player_previous_button",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable swipe to dismiss mini player
|
||||||
|
|
||||||
|
var swipeToDismissWidgetIndex by Delegates.notNull<Int>()
|
||||||
|
lateinit var swipeToDismissIGetObjectReference: Reference
|
||||||
|
lateinit var swipeToDismissInvokeInterfacePrimaryReference: Reference
|
||||||
|
lateinit var swipeToDismissCheckCastReference: Reference
|
||||||
|
lateinit var swipeToDismissSGetObjectReference: Reference
|
||||||
|
lateinit var swipeToDismissNewInstanceReference: Reference
|
||||||
|
lateinit var swipeToDismissInvokeStaticReference: Reference
|
||||||
|
lateinit var swipeToDismissInvokeDirectReference: Reference
|
||||||
|
lateinit var swipeToDismissInvokeInterfaceSecondaryReference: Reference
|
||||||
|
|
||||||
|
fun MutableMethod.getSwipeToDismissReference(
|
||||||
|
opcode: Opcode,
|
||||||
|
reversed: Boolean
|
||||||
|
): Reference {
|
||||||
|
val targetIndex = if (reversed)
|
||||||
|
getTargetIndexReversed(swipeToDismissWidgetIndex, opcode)
|
||||||
|
else
|
||||||
|
getTargetIndex(swipeToDismissWidgetIndex, opcode)
|
||||||
|
|
||||||
|
return getInstruction<ReferenceInstruction>(targetIndex).reference
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SettingsPatch.upward0642) {
|
||||||
|
SwipeToCloseFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// region dismiss mini player by swiping down
|
||||||
|
|
||||||
|
InteractionLoggingEnumFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val stringIndex = getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE")
|
||||||
|
val sPutObjectIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT)
|
||||||
|
|
||||||
|
swipeToDismissSGetObjectReference = getInstruction<ReferenceInstruction>(sPutObjectIndex).reference
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicActivityWidgetFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
swipeToDismissWidgetIndex = getWideLiteralInstructionIndex(79500)
|
||||||
|
|
||||||
|
swipeToDismissIGetObjectReference = getSwipeToDismissReference(Opcode.IGET_OBJECT, true)
|
||||||
|
swipeToDismissInvokeInterfacePrimaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, true)
|
||||||
|
swipeToDismissCheckCastReference = getSwipeToDismissReference(Opcode.CHECK_CAST, true)
|
||||||
|
swipeToDismissNewInstanceReference = getSwipeToDismissReference(Opcode.NEW_INSTANCE, true)
|
||||||
|
swipeToDismissInvokeStaticReference = getSwipeToDismissReference(Opcode.INVOKE_STATIC, false)
|
||||||
|
swipeToDismissInvokeDirectReference = getSwipeToDismissReference(Opcode.INVOKE_DIRECT, false)
|
||||||
|
swipeToDismissInvokeInterfaceSecondaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleSearchRenderedFingerprint.resultOrThrow().let { parentResult ->
|
||||||
|
// resolves fingerprints
|
||||||
|
HandleSignInEventFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
|
HandleSignInEventFingerprint.resultOrThrow().let {
|
||||||
|
val dismissBehaviorMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
|
||||||
|
|
||||||
|
dismissBehaviorMethod.apply {
|
||||||
|
val insertIndex = getTargetIndexWithFieldReferenceType("Ljava/util/concurrent/atomic/AtomicBoolean;")
|
||||||
|
val primaryRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
||||||
|
val secondaryRegister = primaryRegister + 1
|
||||||
|
val tertiaryRegister = secondaryRegister + 1
|
||||||
|
|
||||||
|
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z
|
||||||
|
move-result v$freeRegister
|
||||||
|
if-nez v$freeRegister, :dismiss
|
||||||
|
iget-object v$primaryRegister, v$primaryRegister, $swipeToDismissIGetObjectReference
|
||||||
|
invoke-interface {v$primaryRegister}, $swipeToDismissInvokeInterfacePrimaryReference
|
||||||
|
move-result-object v$primaryRegister
|
||||||
|
check-cast v$primaryRegister, $swipeToDismissCheckCastReference
|
||||||
|
sget-object v$secondaryRegister, $swipeToDismissSGetObjectReference
|
||||||
|
new-instance v$tertiaryRegister, $swipeToDismissNewInstanceReference
|
||||||
|
const p0, 0x878b
|
||||||
|
invoke-static {p0}, $swipeToDismissInvokeStaticReference
|
||||||
|
move-result-object p0
|
||||||
|
invoke-direct {v$tertiaryRegister, p0}, $swipeToDismissInvokeDirectReference
|
||||||
|
const/4 p0, 0x0
|
||||||
|
invoke-interface {v$primaryRegister, v$secondaryRegister, v$tertiaryRegister, p0}, $swipeToDismissInvokeInterfaceSecondaryReference
|
||||||
|
return-void
|
||||||
|
""", ExternalLabel("dismiss", getInstruction(insertIndex))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region hides default text display when the app is cold started
|
||||||
|
|
||||||
|
MiniPlayerDefaultTextFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
|
move-result-object v$insertRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region hides default text display after dismissing the mini player
|
||||||
|
|
||||||
|
MiniPlayerDefaultViewVisibilityFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableClass.methods.find { method ->
|
||||||
|
method.parameters == listOf("Landroid/view/View;", "I")
|
||||||
|
}?.apply {
|
||||||
|
val bottomSheetBehaviorIndex = implementation!!.instructions.indexOfFirst { instruction ->
|
||||||
|
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
||||||
|
&& instruction.getReference<MethodReference>()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
|
||||||
|
&& instruction.getReference<MethodReference>()?.parameterTypes?.first() == "Z"
|
||||||
|
}
|
||||||
|
if (bottomSheetBehaviorIndex < 0)
|
||||||
|
throw PatchException("Could not find bottomSheetBehaviorIndex")
|
||||||
|
|
||||||
|
val freeRegister = getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
bottomSheetBehaviorIndex - 2, """
|
||||||
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z
|
||||||
|
move-result v$freeRegister
|
||||||
|
if-nez v$freeRegister, :dismiss
|
||||||
|
""", ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1))
|
||||||
|
)
|
||||||
|
} ?: throw PatchException("Could not find targetMethod")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_swipe_to_dismiss_mini_player",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for enable zen mode
|
||||||
|
|
||||||
|
MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult ->
|
||||||
|
// resolves fingerprints
|
||||||
|
SwitchToggleColorFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
ZenModeFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
|
// this method is used for old player background (deprecated since YT Music v6.34.51)
|
||||||
|
ZenModeFingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
||||||
|
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} // no exception
|
||||||
|
|
||||||
|
SwitchToggleColorFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val invokeDirectIndex = getTargetIndex(Opcode.INVOKE_DIRECT)
|
||||||
|
val walkerMethod = getWalkerMethod(context, invokeDirectIndex)
|
||||||
|
|
||||||
|
walkerMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I
|
||||||
|
move-result p1
|
||||||
|
invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I
|
||||||
|
move-result p2
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_zen_mode",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_enable_zen_mode_podcast",
|
||||||
|
"false",
|
||||||
|
"revanced_enable_zen_mode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for hide channel guideline, timestamps & emoji picker buttons
|
||||||
|
|
||||||
|
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_hide_comment_channel_guidelines",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_hide_comment_timestamp_and_emoji_buttons",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
|
||||||
|
// region patch for hide fullscreen share button
|
||||||
|
|
||||||
|
RemixGenericButtonFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex + 1, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideFullscreenShareButton(I)I
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_hide_fullscreen_share_button",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for remember repeat state
|
||||||
|
|
||||||
|
RepeatTrackFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->rememberRepeatState(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_remember_repeat_state",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for remember shuffle state
|
||||||
|
|
||||||
|
val MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR =
|
||||||
|
"Lcom/google/android/apps/youtube/music/watchpage/MusicPlaybackControls;"
|
||||||
|
|
||||||
|
lateinit var rememberShuffleStateObjectClass: String
|
||||||
|
lateinit var rememberShuffleStateImageViewReference: Reference
|
||||||
|
lateinit var rememberShuffleStateShuffleStateLabel: String
|
||||||
|
|
||||||
|
ShuffleClassReferenceFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
rememberShuffleStateObjectClass = definingClass
|
||||||
|
|
||||||
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val imageViewIndex = getTargetIndexWithFieldReferenceType("Landroid/widget/ImageView;")
|
||||||
|
|
||||||
|
val shuffleReference1 = getInstruction<ReferenceInstruction>(startIndex).reference
|
||||||
|
val shuffleReference2 = getInstruction<ReferenceInstruction>(startIndex + 1).reference
|
||||||
|
val shuffleReference3 = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||||
|
val shuffleFieldReference = shuffleReference3 as FieldReference
|
||||||
|
rememberShuffleStateImageViewReference = getInstruction<ReferenceInstruction>(imageViewIndex).reference
|
||||||
|
|
||||||
|
rememberShuffleStateShuffleStateLabel = """
|
||||||
|
iget-object v1, v0, $shuffleReference1
|
||||||
|
invoke-interface {v1}, $shuffleReference2
|
||||||
|
move-result-object v1
|
||||||
|
check-cast v1, ${shuffleFieldReference.definingClass}
|
||||||
|
iget-object v1, v1, $shuffleReference3
|
||||||
|
invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I
|
||||||
|
move-result v1
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
|
val constructorMethod =
|
||||||
|
it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) }
|
||||||
|
val onClickMethod = it.mutableClass.methods.first { method -> method.name == "onClick" }
|
||||||
|
|
||||||
|
constructorMethod.apply {
|
||||||
|
addInstruction(
|
||||||
|
implementation!!.instructions.size - 1,
|
||||||
|
"sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickMethod.apply {
|
||||||
|
addInstructions(
|
||||||
|
0, """
|
||||||
|
move-object v0, p0
|
||||||
|
""" + rememberShuffleStateShuffleStateLabel + """
|
||||||
|
invoke-static {v1}, $PLAYER_CLASS_DESCRIPTOR->setShuffleState(I)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.traverseClassHierarchy(it.mutableClass) {
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL
|
||||||
|
transformFields {
|
||||||
|
ImmutableField(
|
||||||
|
definingClass,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.PUBLIC,
|
||||||
|
null,
|
||||||
|
annotations,
|
||||||
|
null
|
||||||
|
).toMutable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicPlaybackControlsFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-virtual {v0}, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->rememberShuffleState()V"
|
||||||
|
)
|
||||||
|
|
||||||
|
val shuffleField = ImmutableField(
|
||||||
|
definingClass,
|
||||||
|
"shuffleClass",
|
||||||
|
rememberShuffleStateObjectClass,
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
null,
|
||||||
|
annotations,
|
||||||
|
null
|
||||||
|
).toMutable()
|
||||||
|
|
||||||
|
val shuffleMethod = ImmutableMethod(
|
||||||
|
definingClass,
|
||||||
|
"rememberShuffleState",
|
||||||
|
emptyList(),
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
annotations, null,
|
||||||
|
MutableMethodImplementation(5)
|
||||||
|
).toMutable()
|
||||||
|
|
||||||
|
shuffleMethod.addInstructionsWithLabels(
|
||||||
|
0, """
|
||||||
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->getShuffleState()I
|
||||||
|
move-result v2
|
||||||
|
if-nez v2, :dont_shuffle
|
||||||
|
sget-object v0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass
|
||||||
|
""" + rememberShuffleStateShuffleStateLabel + """
|
||||||
|
iget-object v3, v0, $rememberShuffleStateImageViewReference
|
||||||
|
invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z
|
||||||
|
if-eqz v1, :dont_shuffle
|
||||||
|
invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z
|
||||||
|
:dont_shuffle
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
it.mutableClass.methods.add(shuffleMethod)
|
||||||
|
it.mutableClass.staticFields.add(shuffleField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_remember_shuffle_state",
|
||||||
|
"true"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for restore old comments popup panels
|
||||||
|
|
||||||
|
OldEngagementPanelFingerprint.literalInstructionBooleanHook(
|
||||||
|
45427672,
|
||||||
|
"$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z"
|
||||||
|
)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_restore_old_comments_popup_panels",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for restore old player background
|
||||||
|
|
||||||
|
OldPlayerBackgroundFingerprint.result?.let {
|
||||||
|
OldPlayerBackgroundFingerprint.literalInstructionBooleanHook(
|
||||||
|
45415319,
|
||||||
|
"$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerBackground(Z)Z"
|
||||||
|
)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_restore_old_player_background",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region patch for restore old player layout
|
||||||
|
|
||||||
|
OldPlayerLayoutFingerprint.result?.let {
|
||||||
|
OldPlayerLayoutFingerprint.literalInstructionBooleanHook(
|
||||||
|
45399578,
|
||||||
|
"$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerLayout(Z)Z"
|
||||||
|
)
|
||||||
|
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.PLAYER,
|
||||||
|
"revanced_restore_old_player_layout",
|
||||||
|
"false"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setInstanceFieldValue(
|
||||||
|
methodName: String,
|
||||||
|
viewId: Long
|
||||||
|
) {
|
||||||
|
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
|
val miniPlayerPlayPauseReplayButtonRegister = getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
||||||
|
val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val parentViewRegister = getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
miniPlayerPlayPauseReplayButtonIndex, """
|
||||||
|
const v$miniPlayerPlayPauseReplayButtonRegister, $viewId
|
||||||
|
invoke-virtual {v$parentViewRegister, v$miniPlayerPlayPauseReplayButtonRegister}, Landroid/view/View;->findViewById(I)Landroid/view/View;
|
||||||
|
move-result-object v$miniPlayerPlayPauseReplayButtonRegister
|
||||||
|
invoke-static {v$miniPlayerPlayPauseReplayButtonRegister}, $PLAYER_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setStaticFieldValue(
|
||||||
|
fieldName: String,
|
||||||
|
viewId: Long
|
||||||
|
) {
|
||||||
|
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
|
val constRegister = getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
||||||
|
val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val findViewByIdRegister = getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
miniPlayerPlayPauseReplayButtonIndex, """
|
||||||
|
const v$constRegister, $viewId
|
||||||
|
invoke-virtual {v$findViewByIdRegister, v$constRegister}, $definingClass->findViewById(I)Landroid/view/View;
|
||||||
|
move-result-object v$constRegister
|
||||||
|
sput-object v$constRegister, $PLAYER_CLASS_DESCRIPTOR->$fieldName:Landroid/view/View;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setViewArray() {
|
||||||
|
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
|
val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC)
|
||||||
|
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
invokeStaticIndex, """
|
||||||
|
invoke-static {v$viewArrayRegister}, $PLAYER_CLASS_DESCRIPTOR->getViewArray([Landroid/view/View;)[Landroid/view/View;
|
||||||
|
move-result-object v$viewArrayRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setOnClickListener(
|
||||||
|
context: BytecodeContext,
|
||||||
|
intentString: String,
|
||||||
|
methodName: String,
|
||||||
|
fieldName: String
|
||||||
|
) {
|
||||||
|
val startIndex = getStringInstructionIndex(intentString)
|
||||||
|
val onClickIndex = getTargetIndexReversed(startIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val onClickReference = getInstruction<ReferenceInstruction>(onClickIndex).reference
|
||||||
|
val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass
|
||||||
|
|
||||||
|
val onClickClass =
|
||||||
|
context.findClass(onClickReferenceDefiningClass)!!.mutableClass
|
||||||
|
|
||||||
|
onClickClass.methods.find { method -> method.name == "<init>" }
|
||||||
|
?.apply {
|
||||||
|
addInstruction(
|
||||||
|
implementation!!.instructions.size - 1,
|
||||||
|
"sput-object p0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass"
|
||||||
|
)
|
||||||
|
} ?: throw PatchException("onClickClass not found!")
|
||||||
|
|
||||||
|
PlayerPatchConstructorFingerprint.resultOrThrow().let {
|
||||||
|
val mutableClass = it.mutableClass
|
||||||
|
mutableClass.methods.find { method -> method.name == methodName }
|
||||||
|
?.apply {
|
||||||
|
mutableClass.staticFields.add(
|
||||||
|
ImmutableField(
|
||||||
|
definingClass,
|
||||||
|
fieldName,
|
||||||
|
onClickReferenceDefiningClass,
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
null,
|
||||||
|
annotations,
|
||||||
|
null
|
||||||
|
).toMutable()
|
||||||
|
)
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0, """
|
||||||
|
sget-object v0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass
|
||||||
|
if-eqz v0, :ignore
|
||||||
|
invoke-virtual {v0}, $onClickReference
|
||||||
|
:ignore
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
@file:Suppress("DEPRECATION")
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package app.revanced.patches.music.player.nextprevious
|
package app.revanced.patches.music.player.components
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
@ -14,7 +14,7 @@ import org.w3c.dom.Element
|
|||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
|
||||||
@Patch(dependencies = [SettingsPatch::class])
|
@Patch(dependencies = [SettingsPatch::class])
|
||||||
object MiniPlayerButtonResourcePatch : ResourcePatch(), Closeable {
|
object PlayerComponentsResourcePatch : ResourcePatch(), Closeable {
|
||||||
private const val IMAGE_VIEW_TAG_NAME =
|
private const val IMAGE_VIEW_TAG_NAME =
|
||||||
"com.google.android.libraries.youtube.common.ui.TouchImageView"
|
"com.google.android.libraries.youtube.common.ui.TouchImageView"
|
||||||
private const val NEXT_BUTTON_VIEW_ID =
|
private const val NEXT_BUTTON_VIEW_ID =
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.utils.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerDefaultText
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerDefaultText
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.nextprevious.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerMdxPlaying
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerMdxPlaying
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.minimizedplayer.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.nextprevious.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.swipetodismiss.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
import app.revanced.util.containsWideLiteralInstructionIndex
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.shuffle.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.nextprevious.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
@ -0,0 +1,9 @@
|
|||||||
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
||||||
|
internal object OldEngagementPanelFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
parameters = emptyList(),
|
||||||
|
literalSupplier = { 45427672 }
|
||||||
|
)
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.oldplayerbackground.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.music.player.oldplayerlayout.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user