Skip to content

Commit

Permalink
fix(YouTube Music - Hide ads): The Hide fullscreen ads setting does…
Browse files Browse the repository at this point in the history
… not fully hide fullscreen ads
  • Loading branch information
anddea committed Feb 11, 2025
1 parent d5b1ebe commit 821e89e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -37,16 +43,29 @@ public static boolean disableFullscreenAds(final byte[] bytes, int type) {

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
);
}
Expand All @@ -64,8 +83,8 @@ private enum DialogType {
}

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

@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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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;
Expand Down Expand Up @@ -53,7 +52,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,12 @@ val adsPatch = bytecodePatch(

addLithoFilter(ADS_FILTER_CLASS_DESCRIPTOR)

// endregion

addSwitchPreference(
CategoryType.ADS,
"revanced_hide_fullscreen_ads",
"false"
"true"
)
addSwitchPreference(
CategoryType.ADS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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
"""
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -151,13 +149,6 @@ val adsPatch = bytecodePatch(

// endregion

findMethodOrThrow("$PATCHES_PATH/PatchStatus;") {
name == "HideFullscreenAdsDefaultBoolean"
}.replaceInstruction(
0,
"const/4 v0, 0x1"
)

// region add settings

addPreference(
Expand Down

0 comments on commit 821e89e

Please sign in to comment.