fix(YouTube Music - Hide ads): Hide fullscreen ads setting does not completely hide the fullscreen ads https://github.com/inotia00/ReVanced_Extended/issues/2515

This commit is contained in:
inotia00 2025-02-10 16:21:07 +09:00
parent 7667b70c67
commit af447be6cc
7 changed files with 58 additions and 39 deletions

View File

@ -1,34 +1,40 @@
package app.revanced.extension.shared.patches;
import static app.revanced.extension.shared.utils.StringRef.str;
import static app.revanced.extension.shared.utils.Utils.hideViewBy0dpUnderCondition;
import android.app.Dialog;
import android.view.View;
import app.revanced.extension.shared.patches.components.ByteArrayFilterGroup;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.Utils;
@SuppressWarnings("unused")
public class FullscreenAdsPatch {
private static final boolean hideFullscreenAdsEnabled = BaseSettings.HIDE_FULLSCREEN_ADS.get();
private static final boolean HIDE_FULLSCREEN_ADS =
BaseSettings.HIDE_FULLSCREEN_ADS.get();
private static final ByteArrayFilterGroup exception =
new ByteArrayFilterGroup(
null,
"post_image_lightbox.eml" // Community post image in fullscreen
);
public static boolean disableFullscreenAds(final byte[] bytes, int type) {
if (!hideFullscreenAdsEnabled) {
return false;
}
private static boolean isFullscreenAds = false;
public static void checkDialog(byte[] bytes, int type) {
if (!HIDE_FULLSCREEN_ADS) {
return;
}
final DialogType dialogType = DialogType.getDialogType(type);
final String dialogName = dialogType.name();
// The dialog type of a fullscreen dialog is always {@code DialogType.FULLSCREEN}
if (dialogType != DialogType.FULLSCREEN) {
Logger.printDebug(() -> "Ignoring dialogType " + dialogName);
return false;
isFullscreenAds = false;
return;
}
// Image in community post in fullscreen is not filtered
@ -37,16 +43,29 @@ public class FullscreenAdsPatch {
if (isException) {
Logger.printDebug(() -> "Ignoring exception");
} else {
Logger.printDebug(() -> "Blocked fullscreen ads");
}
isFullscreenAds = !isException;
}
return !isException;
public static void dismissDialog(Object customDialog) {
if (!isFullscreenAds) {
return;
}
if (customDialog instanceof Dialog dialog) {
dialog.hide();
// Perhaps this is not necessary.
dialog.dismiss();
if (BaseSettings.ENABLE_DEBUG_LOGGING.get()) {
Utils.showToastShort(str("revanced_fullscreen_ads_closed_toast"));
}
} else {
Logger.printDebug(() -> "customDialog type: " + customDialog.getClass().getName());
}
}
public static void hideFullscreenAds(View view) {
hideViewBy0dpUnderCondition(
hideFullscreenAdsEnabled,
HIDE_FULLSCREEN_ADS,
view
);
}
@ -64,8 +83,8 @@ public class FullscreenAdsPatch {
}
private static DialogType getDialogType(int type) {
for (DialogType val : values())
if (type == val.type) return val;
for (DialogType dialogType : values())
if (type == dialogType.type) return dialogType;
return DialogType.NULL;
}

View File

@ -2,10 +2,6 @@ package app.revanced.extension.shared.patches;
@SuppressWarnings("unused")
public class PatchStatus {
public static boolean HideFullscreenAdsDefaultBoolean() {
return false;
}
public static boolean SpoofClient() {
// Replace this with true If the Spoof client patch succeeds in YouTube Music.
return false;

View File

@ -2,7 +2,6 @@ package app.revanced.extension.shared.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.patches.PatchStatus.HideFullscreenAdsDefaultBoolean;
import app.revanced.extension.shared.patches.ReturnYouTubeUsernamePatch.DisplayFormat;
import app.revanced.extension.shared.patches.WatchHistoryPatch.WatchHistoryType;
@ -52,7 +51,7 @@ public class BaseSettings {
/**
* These settings are used by YouTube and YouTube Music.
*/
public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", HideFullscreenAdsDefaultBoolean(), true);
public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE, true);
public static final BooleanSetting HIDE_PROMOTION_ALERT_BANNER = new BooleanSetting("revanced_hide_promotion_alert_banner", TRUE);
public static final BooleanSetting DISABLE_AUTO_CAPTIONS = new BooleanSetting("revanced_disable_auto_captions", FALSE, true);

View File

@ -150,10 +150,12 @@ val adsPatch = bytecodePatch(
addLithoFilter(ADS_FILTER_CLASS_DESCRIPTOR)
// endregion
addSwitchPreference(
CategoryType.ADS,
"revanced_hide_fullscreen_ads",
"false"
"true"
)
addSwitchPreference(
CategoryType.ADS,

View File

@ -16,6 +16,7 @@ import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
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.reference.FieldReference
@ -91,17 +92,32 @@ internal fun MutableMethod.hookNonLithoFullscreenAds(literal: Long) {
internal fun Match.hookLithoFullscreenAds() {
method.apply {
// It is ideal to check the dialog type and protobuffer before closing the dialog.
// There is no register that can be used freely, so it is divided into two hooking.
val showDialogIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "show"
}
val dialogRegister = getInstruction<FiveRegisterInstruction>(showDialogIndex).registerC
addInstruction(
showDialogIndex + 1,
"invoke-static {v$dialogRegister}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialog(Ljava/lang/Object;)V"
)
// Dialog type should be checked first.
val dialogCodeIndex = patternMatch!!.endIndex
val dialogCodeField =
getInstruction<ReferenceInstruction>(dialogCodeIndex).reference as FieldReference
if (dialogCodeField.type != "I")
if (dialogCodeField.type != "I") {
throw PatchException("Invalid dialogCodeField: $dialogCodeField")
}
var prependInstructions = """
move-object/from16 v0, p1
move-object/from16 v1, p2
"""
// Used only in very old versions.
if (parameterTypes.firstOrNull() != "[B") {
val toByteArrayReference = getInstruction<ReferenceInstruction>(
indexOfFirstInstructionOrThrow {
@ -116,15 +132,12 @@ internal fun Match.hookLithoFullscreenAds() {
}
// Disable fullscreen ads
addInstructionsWithLabels(
addInstructions(
0, prependInstructions + """
check-cast v1, ${dialogCodeField.definingClass}
iget v1, v1, $dialogCodeField
invoke-static {v0, v1}, $EXTENSION_CLASS_DESCRIPTOR->disableFullscreenAds([BI)Z
move-result v1
if-eqz v1, :show
return-void
""", ExternalLabel("show", getInstruction(0))
invoke-static {v0, v1}, $EXTENSION_CLASS_DESCRIPTOR->checkDialog([BI)V
"""
)
}
}

View File

@ -8,7 +8,6 @@ import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.ads.baseAdsPatch
import app.revanced.patches.shared.ads.hookLithoFullscreenAds
import app.revanced.patches.shared.ads.hookNonLithoFullscreenAds
import app.revanced.patches.shared.extension.Constants.PATCHES_PATH
import app.revanced.patches.shared.litho.addLithoFilter
import app.revanced.patches.shared.litho.lithoFilterPatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
@ -22,7 +21,6 @@ import app.revanced.patches.youtube.utils.resourceid.interstitialsContainer
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.findMethodOrThrow
import app.revanced.util.findMutableMethodOf
import app.revanced.util.fingerprint.matchOrThrow
import app.revanced.util.fingerprint.methodOrThrow
@ -151,13 +149,6 @@ val adsPatch = bytecodePatch(
// endregion
findMethodOrThrow("$PATCHES_PATH/PatchStatus;") {
name == "HideFullscreenAdsDefaultBoolean"
}.replaceInstruction(
0,
"const/4 v0, 0x1"
)
// region add settings
addPreference(

View File

@ -58,10 +58,8 @@ Please download %2$s from the website."</string>
<string name="revanced_preference_screen_ads_title">Ads</string>
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
<string name="revanced_hide_fullscreen_ads_summary">"Hides fullscreen ads.
Limitations:
• Sometimes you may see a blank black screen instead of the home feed."</string>
<string name="revanced_hide_fullscreen_ads_summary">Hides fullscreen ads.</string>
<string name="revanced_fullscreen_ads_closed_toast">Fullscreen ads are closed.</string>
<string name="revanced_hide_general_ads_title">Hide general ads</string>
<string name="revanced_hide_general_ads_summary">Hides general ads.</string>
<string name="revanced_hide_music_ads_title">Hide media ads</string>
@ -70,6 +68,7 @@ Limitations:
<string name="revanced_hide_paid_promotion_label_summary">Hides the paid promotion label.</string>
<string name="revanced_hide_premium_promotion_title">Hide premium promotion popups</string>
<string name="revanced_hide_premium_promotion_summary">Hides the premium promotion popups.</string>
<string name="revanced_hide_premium_promotion_closed_toast">Premium promotion popups are closed.</string>
<string name="revanced_hide_premium_renewal_title">Hide premium renewal banner</string>
<string name="revanced_hide_premium_renewal_summary">Hides the premium renewal banner.</string>
<string name="revanced_hide_promotion_alert_banner_title">Hide promotion alert banner</string>