feat(YouTube): Hide search term thumbnail, Hide toolbar button, Hide trending searches, Hide voice search button patches has been integrated into Toolbar components patch

This commit is contained in:
inotia00
2024-04-27 04:48:04 +09:00
parent e6411d946a
commit 9d78f19b74
25 changed files with 534 additions and 366 deletions

View File

@ -15,7 +15,7 @@ object DrawableColorPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext) {
DrawableFingerprint.resultOrThrow().mutableMethod?.apply {
DrawableFingerprint.resultOrThrow().mutableMethod.apply {
insertMethod = this
insertIndex = getTargetIndexWithMethodReferenceNameReversed("setColor")
insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD

View File

@ -5,45 +5,30 @@ 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.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.shared.litho.LithoFilterPatch
import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml
import app.revanced.patches.youtube.general.components.fingerprints.AccountListFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.AccountListParentFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.AccountMenuFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.AccountSwitcherAccessibilityLabelFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.BottomUiContainerFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.CreateSearchSuggestionsFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.FloatingMicrophoneFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.TrendingSearchConfigFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.SearchBarFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.SearchBarParentFingerprint
import app.revanced.patches.youtube.general.components.fingerprints.SearchResultFingerprint
import app.revanced.patches.youtube.utils.fingerprints.AccountMenuParentFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VoiceSearch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
import app.revanced.patches.youtube.utils.viewgroup.ViewGroupMarginLayoutParamsHookPatch
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getTargetIndexWithReferenceReversed
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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Suppress("unused")
@ -54,7 +39,6 @@ object LayoutComponentsPatch : BaseBytecodePatch(
LithoFilterPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class,
ToolBarHookPatch::class,
ViewGroupMarginLayoutParamsHookPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE,
@ -63,11 +47,7 @@ object LayoutComponentsPatch : BaseBytecodePatch(
AccountMenuParentFingerprint,
AccountSwitcherAccessibilityLabelFingerprint,
BottomUiContainerFingerprint,
CreateSearchSuggestionsFingerprint,
FloatingMicrophoneFingerprint,
SearchBarParentFingerprint,
SearchResultFingerprint,
TrendingSearchConfigFingerprint
FloatingMicrophoneFingerprint
)
) {
private const val CUSTOM_FILTER_CLASS_DESCRIPTOR =
@ -75,13 +55,6 @@ object LayoutComponentsPatch : BaseBytecodePatch(
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) {
// region patch for hide account menu
@ -124,22 +97,6 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// endregion
// region patch for hide cast button
val buttonClass = context.findClass("MediaRouteButton")
?: throw PatchException("MediaRouteButton class not found.")
buttonClass.mutableClass.methods.find { it.name == "setVisibility" }?.apply {
addInstructions(
0, """
invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result p1
"""
)
} ?: throw PatchException("setVisibility method not found.")
// endregion
// region patch for hide floating microphone
FloatingMicrophoneFingerprint.resultOrThrow().let {
@ -178,39 +135,6 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// endregion
// region patch for hide search term thumbnail
CreateSearchSuggestionsFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply {
val relativeIndex = getWideLiteralInstructionIndex(40)
val replaceIndex = getTargetIndexWithReferenceReversed(
relativeIndex,
"Landroid/widget/ImageView;->setVisibility(I)V"
) - 1
val jumpIndex = getTargetIndexWithReference(
relativeIndex,
"Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
) + 4
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
val replaceIndexReference =
getInstruction<ReferenceInstruction>(replaceIndex).reference
addInstructionsWithLabels(
replaceIndex + 1, """
invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z
move-result v${replaceIndexInstruction.registerA}
if-nez v${replaceIndexInstruction.registerA}, :hidden
iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference
""", ExternalLabel("hidden", getInstruction(jumpIndex))
)
removeInstruction(replaceIndex)
}
}
// endregion
// region patch for hide snack bar
BottomUiContainerFingerprint.resultOrThrow().let {
@ -228,80 +152,6 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// endregion
// region patch for hide toolbar button
ToolBarHookPatch.injectCall("$GENERAL_CLASS_DESCRIPTOR->hideToolBarButton")
// endregion
// region patch for hide trending searches
TrendingSearchConfigFingerprint.literalInstructionBooleanHook(
45399984,
"$GENERAL_CLASS_DESCRIPTOR->hideTrendingSearches(Z)Z"
)
// endregion
// region patch for hide voice search button
if (ForceHideVoiceSearchButton == true) {
SettingsPatch.contexts.patchXml(
arrayOf(
"action_bar_search_results_view_mic.xml",
"action_bar_search_view.xml",
"action_bar_search_view_grey.xml",
"action_bar_search_view_mic_out.xml"
),
arrayOf(
"height",
"marginEnd",
"marginStart",
"width"
)
)
} else {
SearchBarFingerprint.resolve(context, SearchBarParentFingerprint.resultOrThrow().classDef)
SearchBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
replaceInstruction(
setVisibilityIndex,
"invoke-static {v${setVisibilityInstruction.registerC}, v${setVisibilityInstruction.registerD}}, " +
"$GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/view/View;I)V"
)
}
}
SearchResultFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
val viewRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
addInstruction(
setOnClickListenerIndex + 1,
"invoke-static {v$viewRegister}, $GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/view/View;)V"
)
}
}
/**
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"SETTINGS: HIDE_VOICE_SEARCH_BUTTON"
)
)
}
// endregion
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR)
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)

View File

@ -0,0 +1,259 @@
package app.revanced.patches.youtube.general.toolbar
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.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml
import app.revanced.patches.youtube.general.toolbar.fingerprints.CreateSearchSuggestionsFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.SearchBarFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.SearchBarParentFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.SearchResultFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.SetActionBarRingoFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.SetWordMarkHeaderFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.TrendingSearchConfigFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.YouActionBarFingerprint
import app.revanced.patches.youtube.utils.castbutton.CastButtonPatch
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VoiceSearch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getTargetIndexWithReferenceReversed
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 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
@Suppress("DEPRECATION", "unused")
object ToolBarComponentsPatch : BaseBytecodePatch(
name = "Toolbar components",
description = "Adds options to hide or change components located on the toolbar such as toolbar buttons, search bar, and header.",
dependencies = setOf(
CastButtonPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class,
ToolBarHookPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
CreateSearchSuggestionsFingerprint,
SearchBarParentFingerprint,
SearchResultFingerprint,
SetActionBarRingoFingerprint,
SetWordMarkHeaderFingerprint,
TrendingSearchConfigFingerprint
)
) {
private const val FLAG = "android:paddingStart"
private const val TARGET_RESOURCE_PATH = "res/layout/action_bar_ringo_background.xml"
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) {
// region patch for enable wide search bar
val parentClassDef = SetActionBarRingoFingerprint.resultOrThrow().classDef
YouActionBarFingerprint.resolve(context, parentClassDef)
SetWordMarkHeaderFingerprint.resultOrThrow().let {
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
walkerMethod.apply {
injectSearchBarHook(
implementation!!.instructions.size - 1,
"enableWideSearchBar"
)
}
}
YouActionBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
injectSearchBarHook(
it.scanResult.patternScanResult!!.endIndex,
"enableWideSearchBarInYouTab"
)
}
}
contexts.xmlEditor[TARGET_RESOURCE_PATH].use { editor ->
val document = editor.file
with(document.getElementsByTagName("RelativeLayout").item(0)) {
if (attributes.getNamedItem(FLAG) != null) return@with
document.createAttribute(FLAG)
.apply { value = "8.0dip" }
.let(attributes::setNamedItem)
}
}
// endregion
// region patch for hide cast button
CastButtonPatch.hookToolBarButton(context)
// endregion
// region patch for hide create button
ToolBarHookPatch.hook("$GENERAL_CLASS_DESCRIPTOR->hideCreateButton")
// endregion
// region patch for hide notification button
ToolBarHookPatch.hook("$GENERAL_CLASS_DESCRIPTOR->hideNotificationButton")
// endregion
// region patch for hide search term thumbnail
CreateSearchSuggestionsFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply {
val relativeIndex = getWideLiteralInstructionIndex(40)
val replaceIndex = getTargetIndexWithReferenceReversed(
relativeIndex,
"Landroid/widget/ImageView;->setVisibility(I)V"
) - 1
val jumpIndex = getTargetIndexWithReference(
relativeIndex,
"Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
) + 4
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
val replaceIndexReference =
getInstruction<ReferenceInstruction>(replaceIndex).reference
addInstructionsWithLabels(
replaceIndex + 1, """
invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z
move-result v${replaceIndexInstruction.registerA}
if-nez v${replaceIndexInstruction.registerA}, :hidden
iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference
""", ExternalLabel("hidden", getInstruction(jumpIndex))
)
removeInstruction(replaceIndex)
}
}
// endregion
// region patch for hide trending searches
TrendingSearchConfigFingerprint.literalInstructionBooleanHook(
45399984,
"$GENERAL_CLASS_DESCRIPTOR->hideTrendingSearches(Z)Z"
)
// endregion
// region patch for hide voice search button
if (ForceHideVoiceSearchButton == true) {
contexts.patchXml(
arrayOf(
"action_bar_search_results_view_mic.xml",
"action_bar_search_view.xml",
"action_bar_search_view_grey.xml",
"action_bar_search_view_mic_out.xml"
),
arrayOf(
"height",
"marginEnd",
"marginStart",
"width"
)
)
} else {
SearchBarFingerprint.resolve(context, SearchBarParentFingerprint.resultOrThrow().classDef)
SearchBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
replaceInstruction(
setVisibilityIndex,
"invoke-static {v${setVisibilityInstruction.registerC}, v${setVisibilityInstruction.registerD}}, " +
"$GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/view/View;I)V"
)
}
}
SearchResultFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
val viewRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
addInstruction(
setOnClickListenerIndex + 1,
"invoke-static {v$viewRegister}, $GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/view/View;)V"
)
}
}
/**
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"SETTINGS: HIDE_VOICE_SEARCH_BUTTON"
)
)
}
// endregion
/**
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE_SCREEN: GENERAL",
"SETTINGS: TOOLBAR_COMPONENTS"
)
)
SettingsPatch.updatePatchStatus(this)
}
private fun MutableMethod.injectSearchBarHook(
insertIndex: Int,
descriptor: String
) {
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->$descriptor(Z)Z
move-result v$insertRegister
"""
)
}
}

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.components.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.components.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
import com.android.tools.smali.dexlib2.Opcode

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.components.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VoiceSearch
import app.revanced.util.fingerprint.LiteralValueFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.components.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.VoiceSearch
import app.revanced.util.fingerprint.LiteralValueFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.widesearchbar.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarRingo
import app.revanced.util.fingerprint.LiteralValueFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.widesearchbar.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.components.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.LiteralValueFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.general.widesearchbar.fingerprints
package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,108 +0,0 @@
package app.revanced.patches.youtube.general.widesearchbar
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.general.widesearchbar.fingerprints.SetActionBarRingoFingerprint
import app.revanced.patches.youtube.general.widesearchbar.fingerprints.SetWordMarkHeaderFingerprint
import app.revanced.patches.youtube.general.widesearchbar.fingerprints.YouActionBarFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
import app.revanced.util.getWalkerMethod
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("DEPRECATION", "unused")
object WideSearchBarPatch : BaseBytecodePatch(
name = "Enable wide search bar",
description = "Adds an option to replace the search icon with a wide search bar. This will hide the YouTube logo when active.",
dependencies = setOf(
SettingsPatch::class,
SharedResourceIdPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
SetActionBarRingoFingerprint,
SetWordMarkHeaderFingerprint
)
) {
private const val FLAG = "android:paddingStart"
private const val TARGET_RESOURCE_PATH = "res/layout/action_bar_ringo_background.xml"
override fun execute(context: BytecodeContext) {
// resolves fingerprints
val parentClassDef = SetActionBarRingoFingerprint.resultOrThrow().classDef
YouActionBarFingerprint.resolve(context, parentClassDef)
// patch methods
SetWordMarkHeaderFingerprint.resultOrThrow().let {
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
walkerMethod.apply {
injectSearchBarHook(
implementation!!.instructions.size - 1,
"enableWideSearchBar"
)
}
}
YouActionBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
injectSearchBarHook(
it.scanResult.patternScanResult!!.endIndex,
"enableWideSearchBarInYouTab"
)
}
}
/**
* Set Wide SearchBar Start Margin
*/
contexts.xmlEditor[TARGET_RESOURCE_PATH].use { editor ->
val document = editor.file
with(document.getElementsByTagName("RelativeLayout").item(0)) {
if (attributes.getNamedItem(FLAG) != null) return@with
document.createAttribute(FLAG)
.apply { value = "8.0dip" }
.let(attributes::setNamedItem)
}
}
/**
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE_SCREEN: GENERAL",
"SETTINGS: ENABLE_WIDE_SEARCH_BAR"
)
)
SettingsPatch.updatePatchStatus(this)
}
/**
* Injects instructions required for certain methods.
*/
private fun MutableMethod.injectSearchBarHook(
insertIndex: Int,
descriptor: String
) {
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->$descriptor(Z)Z
move-result v$insertRegister
"""
)
}
}

View File

@ -13,6 +13,7 @@ import app.revanced.patches.youtube.player.buttons.fingerprints.MusicAppDeeplink
import app.revanced.patches.youtube.player.buttons.fingerprints.PlayerControlsVisibilityModelFingerprint
import app.revanced.patches.youtube.player.buttons.fingerprints.TitleAnchorFingerprint
import app.revanced.patches.youtube.player.buttons.fingerprints.YouTubeControlsOverlaySubtitleButtonFingerprint
import app.revanced.patches.youtube.utils.castbutton.CastButtonPatch
import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
@ -36,6 +37,7 @@ object PlayerButtonsPatch : BaseBytecodePatch(
name = "Hide player buttons",
description = "Adds an option to hide buttons in the video player.",
dependencies = setOf(
CastButtonPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class
),
@ -111,6 +113,12 @@ object PlayerButtonsPatch : BaseBytecodePatch(
// endregion
// region patch for hide cast button
CastButtonPatch.hookPlayerButton(context)
// endregion
// region patch for hide collapse button
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {

View File

@ -23,8 +23,8 @@ import app.revanced.patches.youtube.utils.fingerprints.LayoutConstructorFingerpr
import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AutoNavPreviewStub
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenEngagementPanel
@ -168,7 +168,7 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
}
}
context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "QuickActions")
context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "QuickActions")
// endregion

View File

@ -10,7 +10,7 @@ import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.player.overlaybuttons.fingerprints.OfflineVideoEndpointFingerprint
import app.revanced.patches.youtube.player.overlaybuttons.fingerprints.PiPPlaybackFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.mainactivity.MainActivityResolvePatch
import app.revanced.util.resultOrThrow
import app.revanced.util.updatePatchStatus
@ -52,7 +52,7 @@ object OverlayButtonsBytecodePatch : BytecodePatch(
}
}
context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "OverlayButtons")
context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "OverlayButtons")
}
}

View File

@ -0,0 +1,101 @@
package app.revanced.patches.youtube.utils.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.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.utils.castbutton.fingerprints.MenuItemInitializeFingerprint
import app.revanced.patches.youtube.utils.castbutton.fingerprints.MenuItemVisibilityFingerprint
import app.revanced.patches.youtube.utils.castbutton.fingerprints.PlayerButtonFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.resultOrThrow
import app.revanced.util.updatePatchStatus
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Patch(dependencies = [SharedResourceIdPatch::class])
object CastButtonPatch : BytecodePatch(
setOf(
MenuItemInitializeFingerprint,
PlayerButtonFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$UTILS_PATH/CastButtonPatch;"
private lateinit var playerButtonMethod: MutableMethod
private lateinit var toolbarMenuItemInitializeMethod: MutableMethod
private lateinit var toolbarMenuItemVisibilityMethod: MutableMethod
override fun execute(context: BytecodeContext) {
val toolbarMenuItemInitializeResult = MenuItemInitializeFingerprint.resultOrThrow()
MenuItemVisibilityFingerprint.resolve(context, toolbarMenuItemInitializeResult.classDef)
toolbarMenuItemInitializeMethod = toolbarMenuItemInitializeResult.mutableMethod
toolbarMenuItemVisibilityMethod = MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod
val buttonClass = context.findClass("MediaRouteButton")
?: throw PatchException("MediaRouteButton class not found.")
buttonClass.mutableClass.methods.find { it.name == "setVisibility" }?.apply {
addInstructions(
0, """
invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result p1
"""
)
} ?: throw PatchException("setVisibility method not found.")
}
internal fun hookPlayerButton(context: BytecodeContext) {
playerButtonMethod.apply {
val index = getTargetIndexWithMethodReferenceName("setVisibility")
val instruction = getInstruction<FiveRegisterInstruction>(index)
val viewRegister = instruction.registerC
val visibilityRegister = instruction.registerD
val reference = getInstruction<ReferenceInstruction>(index).reference
addInstructions(
index + 1, """
invoke-static {v$visibilityRegister}, $PLAYER_CLASS_DESCRIPTOR->hideCastButton(I)I
move-result v$visibilityRegister
invoke-virtual {v$viewRegister, v$visibilityRegister}, $reference
"""
)
removeInstruction(index)
}
context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "PlayerButtons")
}
internal fun hookToolBarButton(context: BytecodeContext) {
toolbarMenuItemInitializeMethod.apply {
val index = getTargetIndexWithMethodReferenceName("setShowAsAction") + 1
addInstruction(
index,
"invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/MenuItem;)V"
)
}
toolbarMenuItemVisibilityMethod.addInstructions(
0, """
invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Z)Z
move-result p1
"""
)
context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "ToolBarComponents")
}
}

View File

@ -0,0 +1,13 @@
package app.revanced.patches.youtube.utils.castbutton.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CastMediaRouteButton
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object MenuItemInitializeFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/MenuItem;"),
returnType = "V",
literalSupplier = { CastMediaRouteButton }
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.youtube.utils.castbutton.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object MenuItemVisibilityFingerprint : MethodReferenceNameFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Z"),
reference = { "setVisible" }
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.youtube.utils.castbutton.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object PlayerButtonFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
parameters = emptyList(),
returnType = "V",
literalSupplier = { 11208 }
)

View File

@ -28,6 +28,8 @@ object Constants {
const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;"
const val SHORTS_CLASS_DESCRIPTOR = "$SHORTS_PATH/ShortsPatch;"
const val PATCH_STATUS_CLASS_DESCRIPTOR = "$UTILS_PATH/PatchStatus;"
val COMPATIBLE_PACKAGE = setOf(
Patch.CompatiblePackage(
"com.google.android.youtube",

View File

@ -30,6 +30,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var BarContainerHeight = -1L
var BottomSheetFooterText = -1L
var BottomUiContainerStub = -1L
var CastMediaRouteButton = -1L
var ChannelListSubMenu = -1L
var CompactLink = -1L
var CompactListItem = -1L
@ -103,6 +104,7 @@ object SharedResourceIdPatch : ResourcePatch() {
BarContainerHeight = getId(DIMEN, "bar_container_height")
BottomSheetFooterText = getId(ID, "bottom_sheet_footer_text")
BottomUiContainerStub = getId(ID, "bottom_ui_container_stub")
CastMediaRouteButton = getId(LAYOUT, "castmediaroutebutton")
ChannelListSubMenu = getId(LAYOUT, "channel_list_sub_menu")
CompactLink = getId(LAYOUT, "compact_link")
CompactListItem = getId(LAYOUT, "compact_list_item")

View File

@ -23,6 +23,11 @@ object ToolBarHookPatch : BytecodePatch(
ToolBarPatchFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$UTILS_PATH/ToolBarPatch;"
private lateinit var toolbarMethod: MutableMethod
override fun execute(context: BytecodeContext) {
ToolBarButtonFingerprint.resultOrThrow().let {
@ -51,18 +56,13 @@ object ToolBarHookPatch : BytecodePatch(
}
}
insertMethod = ToolBarPatchFingerprint.resultOrThrow().mutableMethod
toolbarMethod = ToolBarPatchFingerprint.resultOrThrow().mutableMethod
}
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$UTILS_PATH/ToolBarPatch;"
private lateinit var insertMethod: MutableMethod
internal fun injectCall(
internal fun hook(
descriptor: String
) {
insertMethod.addInstructions(
toolbarMethod.addInstructions(
0,
"invoke-static {p0, p1}, $descriptor(Ljava/lang/String;Landroid/view/View;)V"
)

View File

@ -14,7 +14,7 @@ import app.revanced.patches.youtube.utils.fix.shortsplayback.ShortsPlaybackPatch
import app.revanced.patches.youtube.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.VIDEO_PATH
import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch
@ -165,7 +165,7 @@ object VideoPlaybackPatch : BaseBytecodePatch(
VideoInformationPatch.cpnHook("$INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Z)V")
context.updatePatchStatus("$UTILS_PATH/PatchStatus;", "RememberPlaybackSpeed")
context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "RememberPlaybackSpeed")
// endregion