diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/ads/AdsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/ads/AdsPatch.java index 9eb1aa7b1e..f3ba3f78c6 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/ads/AdsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/ads/AdsPatch.java @@ -4,13 +4,25 @@ import android.view.View; +import java.util.List; + +import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") public class AdsPatch { - private static final boolean hideGeneralAdsEnabled = Settings.HIDE_GENERAL_ADS.get(); - private static final boolean hideGetPremiumAdsEnabled = Settings.HIDE_GET_PREMIUM.get(); - private static final boolean hideVideoAdsEnabled = Settings.HIDE_VIDEO_ADS.get(); + private static final boolean HIDE_END_SCREEN_STORE_BANNER = + Settings.HIDE_END_SCREEN_STORE_BANNER.get(); + private static final boolean HIDE_GENERAL_ADS = + Settings.HIDE_GENERAL_ADS.get(); + private static final boolean HIDE_GET_PREMIUM = + Settings.HIDE_GET_PREMIUM.get(); + private static final boolean HIDE_VIDEO_ADS = + Settings.HIDE_VIDEO_ADS.get(); + + // https://encrypted-tbn0.gstatic.com/shopping?q=tbn + private static final String STORE_BANNER_DOMAIN = + "gstatic.com/shopping"; /** * Injection point. @@ -19,18 +31,37 @@ public class AdsPatch { * @param view The view, which shows ads. */ public static void hideAdAttributionView(View view) { - hideViewBy0dpUnderCondition(hideGeneralAdsEnabled, view); + hideViewBy0dpUnderCondition(HIDE_GENERAL_ADS, view); + } + + /** + * Injection point. + * + * @param elementsList List of components of the end screen container. + * @param protobufList Component (ProtobufList). + */ + public static void hideEndScreenStoreBanner(List elementsList, Object protobufList) { + if (HIDE_END_SCREEN_STORE_BANNER && + protobufList.toString().contains(STORE_BANNER_DOMAIN)) { + Logger.printDebug(() -> "Hiding store banner"); + return; + } + + elementsList.add(protobufList); } + /** + * Injection point. + */ public static boolean hideGetPremium() { - return hideGetPremiumAdsEnabled; + return HIDE_GET_PREMIUM; } /** * Injection point. */ public static boolean hideVideoAds() { - return !hideVideoAdsEnabled; + return !HIDE_VIDEO_ADS; } /** @@ -40,7 +71,7 @@ public static boolean hideVideoAds() { * It is presumed to have been deprecated, and if it is confirmed that it is no longer used, remove it. */ public static boolean hideVideoAds(boolean original) { - return !hideVideoAdsEnabled && original; + return !HIDE_VIDEO_ADS && original; } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 5bfbf8bc4a..c2ad583b5f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -48,6 +48,7 @@ @SuppressWarnings("unused") public class Settings extends BaseSettings { // PreferenceScreen: Ads + public static final BooleanSetting HIDE_END_SCREEN_STORE_BANNER = new BooleanSetting("revanced_hide_end_screen_store_banner", TRUE, true); public static final BooleanSetting HIDE_GENERAL_ADS = new BooleanSetting("revanced_hide_general_ads", TRUE); public static final BooleanSetting HIDE_GET_PREMIUM = new BooleanSetting("revanced_hide_get_premium", TRUE, true); public static final BooleanSetting HIDE_MERCHANDISE_SHELF = new BooleanSetting("revanced_hide_merchandise_shelf", TRUE); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt index 5419d11e80..77ae08b4b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt @@ -28,6 +28,7 @@ import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.injectHideViewCall import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c @@ -132,6 +133,24 @@ val adsPatch = bytecodePatch( // endregion + // region patch for hide end screen store banner + + fullScreenEngagementAdContainerFingerprint.methodOrThrow().apply { + val addListIndex = indexOfAddListInstruction(this) + val addListInstruction = + getInstruction(addListIndex) + val listRegister = addListInstruction.registerC + val objectRegister = addListInstruction.registerD + + replaceInstruction( + addListIndex, + "invoke-static { v$listRegister, v$objectRegister }, " + + "$ADS_CLASS_DESCRIPTOR->hideEndScreenStoreBanner(Ljava/util/List;Ljava/lang/Object;)V" + ) + } + + // endregion + findMethodOrThrow("$PATCHES_PATH/PatchStatus;") { name == "HideFullscreenAdsDefaultBoolean" }.replaceInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt index c51509b41a..315b1d9ac3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt @@ -1,11 +1,16 @@ package app.revanced.patches.youtube.ads.general +import app.revanced.patches.youtube.utils.resourceid.fullScreenEngagementAdContainer import app.revanced.patches.youtube.utils.resourceid.interstitialsContainer import app.revanced.patches.youtube.utils.resourceid.slidingDialogAnimation import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversed import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val compactYpcOfferModuleViewFingerprint = legacyFingerprint( name = "compactYpcOfferModuleViewFingerprint", @@ -24,6 +29,23 @@ internal val compactYpcOfferModuleViewFingerprint = legacyFingerprint( } ) +internal val fullScreenEngagementAdContainerFingerprint = legacyFingerprint( + name = "fullScreenEngagementAdContainerFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + literals = listOf(fullScreenEngagementAdContainer), + customFingerprint = { method, _ -> + indexOfAddListInstruction(method) >= 0 + } +) + +internal fun indexOfAddListInstruction(method: Method) = + method.indexOfFirstInstructionReversed { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "add" + } + internal val interstitialsContainerFingerprint = legacyFingerprint( name = "interstitialsContainerFingerprint", returnType = "V", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index f12b03dea1..49c1f1166d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -105,6 +105,8 @@ var floatyBarTopMargin = -1L private set var fullScreenButton = -1L private set +var fullScreenEngagementAdContainer = -1L + private set var fullScreenEngagementOverlay = -1L private set var fullScreenEngagementPanel = -1L @@ -429,6 +431,10 @@ internal val sharedResourceIdPatch = resourcePatch( ID, "fullscreen_button" ] + fullScreenEngagementAdContainer = resourceMappings[ + ID, + "fullscreen_engagement_ad_container" + ] fullScreenEngagementOverlay = resourceMappings[ LAYOUT, "fullscreen_engagement_overlay" diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index e722f2ca67..ecdf04b3b2 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -80,6 +80,9 @@ Please download %2$s from the website." Ads + Hide end screen store banner + Store banner is hidden. + Store banner is shown. Hide fullscreen ads Fullscreen ads are hidden. Fullscreen ads are shown. diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index bac38b8c69..0d4f132723 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -4,6 +4,7 @@