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.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.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.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.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.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.removeInstruction
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.music.actionbar.component.fingerprints.ActionBarComponentFingerprint
|
||||
import app.revanced.patches.music.actionbar.component.fingerprints.LikeDislikeContainerFingerprint
|
||||
import app.revanced.patches.music.actionbar.components.fingerprints.ActionBarComponentFingerprint
|
||||
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.integrations.Constants.ACTIONBAR_CLASS_DESCRIPTOR
|
||||
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
|
||||
|
||||
@Suppress("unused")
|
||||
object ActionBarComponentPatch : BaseBytecodePatch(
|
||||
name = "Hide action bar component",
|
||||
object ActionBarComponentsPatch : BaseBytecodePatch(
|
||||
name = "Hide action bar components",
|
||||
description = "Adds options to hide action bar components and replace the offline download button with an external download button.",
|
||||
dependencies = setOf(
|
||||
SettingsPatch::class,
|
||||
@ -53,7 +53,7 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
||||
|
||||
addInstruction(
|
||||
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
|
||||
@ -132,7 +132,7 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
||||
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.ACTION_BAR,
|
||||
"revanced_hide_action_button_add_to_playlist",
|
||||
"revanced_hide_action_button_like_dislike",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
@ -140,26 +140,16 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
||||
"revanced_hide_action_button_comment",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.ACTION_BAR,
|
||||
"revanced_hide_action_button_add_to_playlist",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.ACTION_BAR,
|
||||
"revanced_hide_action_button_download",
|
||||
"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(
|
||||
CategoryType.ACTION_BAR,
|
||||
"revanced_hide_action_button_share",
|
||||
@ -167,13 +157,23 @@ object ActionBarComponentPatch : BaseBytecodePatch(
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
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"
|
||||
)
|
||||
SettingsPatch.addPreferenceWithIntent(
|
||||
CategoryType.ACTION_BAR,
|
||||
"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.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.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.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.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.GetPremiumTextViewFingerprint
|
||||
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.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.integrations.Constants.ADS_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.SettingsPatch
|
||||
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.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 GeneralAdsPatch : BaseBytecodePatch(
|
||||
name = "Hide general ads",
|
||||
description = "Adds options to hide general ads.",
|
||||
object AdsPatch : BaseBytecodePatch(
|
||||
name = "Hide ads",
|
||||
description = "Adds options to hide ads.",
|
||||
dependencies = setOf(
|
||||
LithoFilterPatch::class,
|
||||
MusicAdsPatch::class,
|
||||
NavigationBarComponentsPatch::class, // for 'Hide upgrade button' setting
|
||||
SettingsPatch::class,
|
||||
SharedResourceIdPatch::class
|
||||
),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
fingerprints = setOf(
|
||||
AccountMenuFooterFingerprint,
|
||||
FloatingLayoutFingerprint,
|
||||
GetPremiumTextViewFingerprint,
|
||||
InterstitialsContainerFingerprint,
|
||||
MembershipSettingsParentFingerprint,
|
||||
NotifierShelfFingerprint,
|
||||
ShowDialogCommandFingerprint
|
||||
)
|
||||
@ -58,10 +73,9 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
/**
|
||||
* Hides fullscreen ads
|
||||
* Non-litho view, used in some old clients.
|
||||
*/
|
||||
// region patch for hide fullscreen ads
|
||||
|
||||
// non-litho view, used in some old clients
|
||||
InterstitialsContainerFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
|
||||
@ -74,10 +88,7 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides fullscreen ads
|
||||
* Litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
||||
*/
|
||||
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
||||
ShowDialogCommandFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
// In this method, custom dialog is created and shown.
|
||||
@ -127,9 +138,10 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides premium promotion popup
|
||||
*/
|
||||
// endregion
|
||||
|
||||
// region patch for hide premium promotion popup
|
||||
|
||||
FloatingLayoutFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(FloatingLayout) + 2
|
||||
@ -142,9 +154,10 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides premium renewal banner
|
||||
*/
|
||||
// endregion
|
||||
|
||||
// region patch for hide premium renewal banner
|
||||
|
||||
NotifierShelfFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
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(
|
||||
CategoryType.ADS,
|
||||
"revanced_hide_fullscreen_ads",
|
||||
@ -175,7 +241,7 @@ object GeneralAdsPatch : BaseBytecodePatch(
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.ADS,
|
||||
"revanced_hide_paid_promotion",
|
||||
"revanced_hide_paid_promotion_label",
|
||||
"true"
|
||||
)
|
||||
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.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.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.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object HideGetPremiumFingerprint : MethodFingerprint(
|
||||
internal object GetPremiumTextViewFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
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.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.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.patch.ResourcePatch
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
|
||||
object ReplaceReportResourcePatch : ResourcePatch() {
|
||||
object FlyoutMenuComponentsResourcePatch : ResourcePatch() {
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
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.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.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.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
|
||||
|
@ -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.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) {
|
||||
|
||||
VideoIdPatch.hookBackgroundPlayVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
||||
VideoIdPatch.hookVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
||||
|
||||
SettingsPatch.addSwitchPreference(
|
||||
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.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
|
||||
|
@ -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 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.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.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.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.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.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.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.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.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")
|
||||
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.",
|
||||
dependencies = setOf(SettingsPatch::class),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
@ -33,7 +33,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
||||
|
||||
addInstructions(
|
||||
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
|
||||
"""
|
||||
)
|
||||
@ -42,7 +42,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch(
|
||||
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.GENERAL,
|
||||
"revanced_enable_old_style_library_shelf",
|
||||
"revanced_restore_old_style_library_shelf",
|
||||
"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.patches.music.general.oldstylelibraryshelf.OldStyleLibraryShelfPatch
|
||||
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.util.copyXmlNode
|
||||
import app.revanced.util.patch.BaseResourcePatch
|
||||
|
||||
@Suppress("unused")
|
||||
@ -13,6 +13,7 @@ object SpoofAppVersionPatch : BaseResourcePatch(
|
||||
description = "Adds options to spoof the YouTube Music client version. " +
|
||||
"This can remove the radio mode restriction in Canadian regions or disable real-time lyrics.",
|
||||
dependencies = setOf(
|
||||
OldStyleLibraryShelfPatch::class,
|
||||
SettingsPatch::class,
|
||||
SpoofAppVersionBytecodePatch::class
|
||||
),
|
||||
@ -20,18 +21,13 @@ object SpoofAppVersionPatch : BaseResourcePatch(
|
||||
) {
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
/**
|
||||
* Copy arrays
|
||||
*/
|
||||
context.copyXmlNode("music/spoofappversion/host", "values/arrays.xml", "resources")
|
||||
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.MISC,
|
||||
CategoryType.GENERAL,
|
||||
"revanced_spoof_app_version",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addPreferenceWithIntent(
|
||||
CategoryType.MISC,
|
||||
CategoryType.GENERAL,
|
||||
"revanced_spoof_app_version_target",
|
||||
"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.settings.CategoryType
|
||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.music.utils.settings.SettingsPatch.contexts
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
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(
|
||||
CategoryType.GENERAL,
|
||||
"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.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
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.util.patch.BaseResourcePatch
|
||||
|
||||
@ -19,7 +18,7 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
|
||||
private val AppNameNotification by stringPatchOption(
|
||||
key = "AppNameNotification",
|
||||
default = APP_NAME_NOTIFICATION,
|
||||
default = APP_NAME_LAUNCHER,
|
||||
values = mapOf(
|
||||
"Full name" to APP_NAME_NOTIFICATION,
|
||||
"Short name" to APP_NAME_LAUNCHER
|
||||
@ -44,7 +43,6 @@ object CustomBrandingNamePatch : BaseResourcePatch(
|
||||
override fun execute(context: ResourceContext) {
|
||||
|
||||
context.removeStringsElements(
|
||||
LANGUAGE_LIST,
|
||||
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")
|
||||
object BitrateDefaultValuePatch : BaseResourcePatch(
|
||||
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
|
||||
) {
|
||||
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.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.MusicBrowserServiceFingerprint
|
||||
import app.revanced.patches.music.misc.minimizedplayback.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 MinimizedPlaybackPatch : BaseBytecodePatch(
|
||||
name = "Enable minimized playback",
|
||||
description = "Enables playback in miniplayer for Kids music.",
|
||||
description = "Enables minimized and background playback.",
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
fingerprints = setOf(MinimizedPlaybackManagerFingerprint)
|
||||
fingerprints = setOf(
|
||||
BackgroundPlaybackFingerprint,
|
||||
DataSavingSettingsFragmentFingerprint,
|
||||
MinimizedPlaybackManagerFingerprint,
|
||||
MusicBrowserServiceFingerprint,
|
||||
PodCastConfigFingerprint,
|
||||
)
|
||||
) {
|
||||
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(
|
||||
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.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
|
||||
|
@ -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.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.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.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.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.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
|
||||
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
|
||||
|
||||
@Suppress("DEPRECATION", "SpellCheckingInspection", "unused")
|
||||
object NavigationBarComponentPatch : BaseBytecodePatch(
|
||||
name = "Hide navigation bar component",
|
||||
description = "Adds options to hide navigation bar components.",
|
||||
object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||
name = "Navigation bar components",
|
||||
description = "Adds options to hide or change components related to navigation bar.",
|
||||
dependencies = setOf(
|
||||
SettingsPatch::class,
|
||||
SharedResourceIdPatch::class
|
||||
),
|
||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||
fingerprints = setOf(TabLayoutTextFingerprint)
|
||||
fingerprints = setOf(
|
||||
TabLayoutFingerprint,
|
||||
TabLayoutTextFingerprint
|
||||
)
|
||||
) {
|
||||
private const val FLAG = "android:layout_weight"
|
||||
private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -94,19 +117,34 @@ object NavigationBarComponentPatch : BaseBytecodePatch(
|
||||
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_explore_button",
|
||||
"revanced_enable_black_navigation_bar",
|
||||
"true"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_navigation_home_button",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_home_button",
|
||||
"revanced_hide_navigation_samples_button",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_library_button",
|
||||
"revanced_hide_navigation_explore_button",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_navigation_library_button",
|
||||
"false"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_navigation_upgrade_button",
|
||||
"true"
|
||||
)
|
||||
SettingsPatch.addSwitchPreference(
|
||||
CategoryType.NAVIGATION,
|
||||
"revanced_hide_navigation_bar",
|
||||
@ -117,15 +155,5 @@ object NavigationBarComponentPatch : BaseBytecodePatch(
|
||||
"revanced_hide_navigation_label",
|
||||
"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.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.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")
|
||||
|
||||
package app.revanced.patches.music.player.nextprevious
|
||||
package app.revanced.patches.music.player.components
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
@ -14,7 +14,7 @@ import org.w3c.dom.Element
|
||||
import java.io.Closeable
|
||||
|
||||
@Patch(dependencies = [SettingsPatch::class])
|
||||
object MiniPlayerButtonResourcePatch : ResourcePatch(), Closeable {
|
||||
object PlayerComponentsResourcePatch : ResourcePatch(), Closeable {
|
||||
private const val IMAGE_VIEW_TAG_NAME =
|
||||
"com.google.android.libraries.youtube.common.ui.TouchImageView"
|
||||
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
|
||||
|
@ -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 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
|
||||
|
@ -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.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.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.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.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.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.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.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.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.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
|
||||
|
@ -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
|
||||
|
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