feat(YouTube/Hide general ads): add Hide fullscreen ads settings

This commit is contained in:
inotia00 2024-03-27 16:26:10 +09:00
parent d8e22cff61
commit b25413cb3b
8 changed files with 137 additions and 1 deletions

View File

@ -0,0 +1,102 @@
package app.revanced.patches.youtube.ads.fullscreen
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.ads.fullscreen.fingerprints.InterstitialsContainerFingerprint
import app.revanced.patches.youtube.ads.fullscreen.fingerprints.ShowDialogCommandFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
import app.revanced.util.exception
import app.revanced.util.getWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(dependencies = [SharedResourceIdPatch::class])
object FullscreenAdsPatch : BytecodePatch(
setOf(
InterstitialsContainerFingerprint,
ShowDialogCommandFingerprint
)
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/AdsFilter;"
override fun execute(context: BytecodeContext) {
/**
* Hides fullscreen ads
* Non-litho view, used in some old clients.
*/
InterstitialsContainerFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(
targetIndex + 1,
"invoke-static {v$targetRegister}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V"
)
}
} ?: throw InterstitialsContainerFingerprint.exception
/**
* Hides fullscreen ads
* Litho view, used in 'ShowDialogCommandOuterClass' in innertube
*/
ShowDialogCommandFingerprint.result?.let {
it.mutableMethod.apply {
// In this method, custom dialog is created and shown.
// There were no issues despite adding “return-void” to the first index.
//
// If an issue occurs due to patching due to server-side changes in the future,
// Find the instruction whose name is "show" in [MethodReference] and click the 'AlertDialog.BUTTON_POSITIVE' button.
//
// In this case, an instruction for 'getButton' must be added to smali, not in integrations
// (This custom dialog cannot be cast to [AlertDialog] or [Dialog])
//
// See the comments below.
addInstructionsWithLabels(
0,
"""
invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds()Z
move-result v0
if-eqz v0, :show
return-void
""", ExternalLabel("show", getInstruction(0))
)
/*
val dialogIndex = getTargetIndexWithMethodReferenceName("show")
val dialogReference = getInstruction<ReferenceInstruction>(dialogIndex).reference
val dialogDefiningClass = (dialogReference as MethodReference).definingClass
val getButtonMethod = context.findClass(dialogDefiningClass)!!
.mutableClass.methods.first { method ->
method.parameters == listOf("I")
&& method.returnType == "Landroid/widget/Button;"
}
val getButtonCall = dialogDefiningClass + "->" + getButtonMethod.name + "(I)Landroid/widget/Button;"
val dialogRegister = getInstruction<FiveRegisterInstruction>(dialogIndex).registerC
val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ)
val freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA
addInstructions(
dialogIndex + 1, """
# Get the 'AlertDialog.BUTTON_POSITIVE' from custom dialog
# Since this custom dialog cannot be cast to AlertDialog or Dialog,
# It should come from smali, not integrations.
const/4 v$freeRegister, -0x1
invoke-virtual {v$dialogRegister, $freeRegister}, $getButtonCall
move-result-object $freeRegister
invoke-static {$freeRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/Button;)V
"""
)
*/
}
} ?: throw ShowDialogCommandFingerprint.exception
}
}

View File

@ -0,0 +1,10 @@
package app.revanced.patches.youtube.ads.fullscreen.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
import app.revanced.util.fingerprint.LiteralValueFingerprint
object InterstitialsContainerFingerprint : LiteralValueFingerprint(
returnType = "V",
strings= listOf("overlay_controller_param"),
literalSupplier = { InterstitialsContainer }
)

View File

@ -0,0 +1,9 @@
package app.revanced.patches.youtube.ads.fullscreen.fingerprints
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
import app.revanced.util.fingerprint.LiteralValueFingerprint
object ShowDialogCommandFingerprint : LiteralValueFingerprint(
returnType = "V",
literalSupplier = { SlidingDialogAnimation }
)

View File

@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.ads.fullscreen.FullscreenAdsPatch
import app.revanced.patches.youtube.ads.getpremium.HideGetPremiumPatch import app.revanced.patches.youtube.ads.getpremium.HideGetPremiumPatch
import app.revanced.patches.youtube.utils.fix.doublebacktoclose.DoubleBackToClosePatch import app.revanced.patches.youtube.utils.fix.doublebacktoclose.DoubleBackToClosePatch
import app.revanced.patches.youtube.utils.fix.swiperefresh.SwipeRefreshPatch import app.revanced.patches.youtube.utils.fix.swiperefresh.SwipeRefreshPatch
@ -20,6 +21,7 @@ import org.w3c.dom.Element
description = "Adds options to hide general ads.", description = "Adds options to hide general ads.",
dependencies = [ dependencies = [
DoubleBackToClosePatch::class, DoubleBackToClosePatch::class,
FullscreenAdsPatch::class,
GeneralAdsBytecodePatch::class, GeneralAdsBytecodePatch::class,
HideGetPremiumPatch::class, HideGetPremiumPatch::class,
LithoFilterPatch::class, LithoFilterPatch::class,

View File

@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.utils.integrations.Constants
import app.revanced.patches.youtube.ads.getpremium.fingerprints.CompactYpcOfferModuleViewFingerprint import app.revanced.patches.youtube.ads.getpremium.fingerprints.CompactYpcOfferModuleViewFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.util.exception import app.revanced.util.exception
@ -13,6 +14,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
object HideGetPremiumPatch : BytecodePatch( object HideGetPremiumPatch : BytecodePatch(
setOf(CompactYpcOfferModuleViewFingerprint) setOf(CompactYpcOfferModuleViewFingerprint)
) { ) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/AdsFilter;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
CompactYpcOfferModuleViewFingerprint.result?.let { CompactYpcOfferModuleViewFingerprint.result?.let {
@ -27,7 +31,7 @@ object HideGetPremiumPatch : BytecodePatch(
addInstructionsWithLabels( addInstructionsWithLabels(
startIndex + 2, """ startIndex + 2, """
invoke-static {}, $COMPONENTS_PATH/AdsFilter;->hideGetPremium()Z invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideGetPremium()Z
move-result v$tempRegister move-result v$tempRegister
if-eqz v$tempRegister, :show if-eqz v$tempRegister, :show
const/4 v$measuredWidthRegister, 0x0 const/4 v$measuredWidthRegister, 0x0

View File

@ -12,6 +12,7 @@ import app.revanced.patches.shared.patch.mapping.ResourceType.ID
import app.revanced.patches.shared.patch.mapping.ResourceType.INTEGER import app.revanced.patches.shared.patch.mapping.ResourceType.INTEGER
import app.revanced.patches.shared.patch.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.patch.mapping.ResourceType.LAYOUT
import app.revanced.patches.shared.patch.mapping.ResourceType.STRING import app.revanced.patches.shared.patch.mapping.ResourceType.STRING
import app.revanced.patches.shared.patch.mapping.ResourceType.STYLE
@Patch(dependencies = [ResourceMappingPatch::class]) @Patch(dependencies = [ResourceMappingPatch::class])
object SharedResourceIdPatch : ResourcePatch() { object SharedResourceIdPatch : ResourcePatch() {
@ -53,6 +54,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var InlineTimeBarColorizedBarPlayedColorDark: Long = -1 var InlineTimeBarColorizedBarPlayedColorDark: Long = -1
var InlineTimeBarPlayedNotHighlightedColor: Long = -1 var InlineTimeBarPlayedNotHighlightedColor: Long = -1
var InsetOverlayViewLayout: Long = -1 var InsetOverlayViewLayout: Long = -1
var InterstitialsContainer: Long = -1
var LiveChatButton: Long = -1 var LiveChatButton: Long = -1
var MenuItemView: Long = -1 var MenuItemView: Long = -1
var MusicAppDeeplinkButtonView: Long = -1 var MusicAppDeeplinkButtonView: Long = -1
@ -77,6 +79,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var Scrubbing: Long = -1 var Scrubbing: Long = -1
var SeekUndoEduOverlayStub: Long = -1 var SeekUndoEduOverlayStub: Long = -1
var SettingsBooleanTimeRangeDialog: Long = -1 var SettingsBooleanTimeRangeDialog: Long = -1
var SlidingDialogAnimation: Long = -1
var SubtitleMenuSettingsFooterInfo: Long = -1 var SubtitleMenuSettingsFooterInfo: Long = -1
var SuggestedAction: Long = -1 var SuggestedAction: Long = -1
var TabsBarTextTabView: Long = -1 var TabsBarTextTabView: Long = -1
@ -139,6 +142,7 @@ object SharedResourceIdPatch : ResourcePatch() {
InlineTimeBarPlayedNotHighlightedColor = InlineTimeBarPlayedNotHighlightedColor =
find(COLOR, "inline_time_bar_played_not_highlighted_color") find(COLOR, "inline_time_bar_played_not_highlighted_color")
InsetOverlayViewLayout = find(ID, "inset_overlay_view_layout") InsetOverlayViewLayout = find(ID, "inset_overlay_view_layout")
InterstitialsContainer = find(ID, "interstitials_container")
LiveChatButton = find(ID, "live_chat_overlay_button") LiveChatButton = find(ID, "live_chat_overlay_button")
MenuItemView = find(ID, "menu_item_view") MenuItemView = find(ID, "menu_item_view")
MusicAppDeeplinkButtonView = find(ID, "music_app_deeplink_button_view") MusicAppDeeplinkButtonView = find(ID, "music_app_deeplink_button_view")
@ -163,6 +167,7 @@ object SharedResourceIdPatch : ResourcePatch() {
Scrubbing = find(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") Scrubbing = find(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing")
SeekUndoEduOverlayStub = find(ID, "seek_undo_edu_overlay_stub") SeekUndoEduOverlayStub = find(ID, "seek_undo_edu_overlay_stub")
SettingsBooleanTimeRangeDialog = find(LAYOUT, "setting_boolean_time_range_dialog") SettingsBooleanTimeRangeDialog = find(LAYOUT, "setting_boolean_time_range_dialog")
SlidingDialogAnimation = find(STYLE, "SlidingDialogAnimation")
SubtitleMenuSettingsFooterInfo = find(STRING, "subtitle_menu_settings_footer_info") SubtitleMenuSettingsFooterInfo = find(STRING, "subtitle_menu_settings_footer_info")
SuggestedAction = find(LAYOUT, "suggested_action") SuggestedAction = find(LAYOUT, "suggested_action")
TabsBarTextTabView = find(ID, "tabs_bar_text_tab_view") TabsBarTextTabView = find(ID, "tabs_bar_text_tab_view")

View File

@ -429,6 +429,9 @@ Some components may not be hidden."</string>
<string name="revanced_hide_for_you_shelf_summary_off">"'For You' shelves are shown."</string> <string name="revanced_hide_for_you_shelf_summary_off">"'For You' shelves are shown."</string>
<string name="revanced_hide_for_you_shelf_summary_on">"'For You' shelves are hidden."</string> <string name="revanced_hide_for_you_shelf_summary_on">"'For You' shelves are hidden."</string>
<string name="revanced_hide_for_you_shelf_title">"Hide 'For You' shelf"</string> <string name="revanced_hide_for_you_shelf_title">"Hide 'For You' shelf"</string>
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown.</string>
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden.</string>
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
<string name="revanced_hide_fullscreen_button_summary_off">Fullscreen button is shown.</string> <string name="revanced_hide_fullscreen_button_summary_off">Fullscreen button is shown.</string>
<string name="revanced_hide_fullscreen_button_summary_on">Fullscreen button is hidden.</string> <string name="revanced_hide_fullscreen_button_summary_on">Fullscreen button is hidden.</string>
<string name="revanced_hide_fullscreen_button_title">Hide fullscreen button</string> <string name="revanced_hide_fullscreen_button_title">Hide fullscreen button</string>

View File

@ -7,6 +7,7 @@
<Preference android:title=" " android:selectable="false" android:summary="@string/revanced_ads" />PREFERENCE: ADS_SETTINGS --> <Preference android:title=" " android:selectable="false" android:summary="@string/revanced_ads" />PREFERENCE: ADS_SETTINGS -->
<!-- SETTINGS: HIDE_GENERAL_ADS <!-- SETTINGS: HIDE_GENERAL_ADS
<SwitchPreference android:title="@string/revanced_hide_fullscreen_ads_title" android:key="revanced_hide_fullscreen_ads" android:defaultValue="true" android:summaryOn="@string/revanced_hide_fullscreen_ads_summary_on" android:summaryOff="@string/revanced_hide_fullscreen_ads_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_general_ads_title" android:key="revanced_hide_general_ads" android:defaultValue="true" android:summaryOn="@string/revanced_hide_general_ads_summary_on" android:summaryOff="@string/revanced_hide_general_ads_summary_off" /> <SwitchPreference android:title="@string/revanced_hide_general_ads_title" android:key="revanced_hide_general_ads" android:defaultValue="true" android:summaryOn="@string/revanced_hide_general_ads_summary_on" android:summaryOff="@string/revanced_hide_general_ads_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_image_shelf_title" android:key="revanced_hide_image_shelf" android:defaultValue="true" android:summaryOn="@string/revanced_hide_image_shelf_summary_on" android:summaryOff="@string/revanced_hide_image_shelf_summary_off" /> <SwitchPreference android:title="@string/revanced_hide_image_shelf_title" android:key="revanced_hide_image_shelf" android:defaultValue="true" android:summaryOn="@string/revanced_hide_image_shelf_summary_on" android:summaryOff="@string/revanced_hide_image_shelf_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_merchandise_shelf_title" android:key="revanced_hide_merchandise_shelf" android:defaultValue="true" android:summaryOn="@string/revanced_hide_merchandise_shelf_summary_on" android:summaryOff="@string/revanced_hide_merchandise_shelf_summary_off" /> <SwitchPreference android:title="@string/revanced_hide_merchandise_shelf_title" android:key="revanced_hide_merchandise_shelf" android:defaultValue="true" android:summaryOn="@string/revanced_hide_merchandise_shelf_summary_on" android:summaryOff="@string/revanced_hide_merchandise_shelf_summary_off" />