fix(YouTube Music - Hide ads): New type of Premium promotion popups are shown

This commit is contained in:
inotia00 2025-02-10 16:40:03 +09:00
parent 1fb36685ad
commit eb181dcf90
5 changed files with 105 additions and 24 deletions

View File

@ -1,40 +1,60 @@
package app.revanced.extension.music.patches.ads; package app.revanced.extension.music.patches.ads;
import static app.revanced.extension.music.patches.general.GeneralPatch.disableDimBehind;
import static app.revanced.extension.shared.utils.StringRef.str;
import android.app.Dialog;
import android.content.DialogInterface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import app.revanced.extension.music.settings.Settings; import app.revanced.extension.music.settings.Settings;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Logger;
import app.revanced.extension.shared.utils.Utils;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class PremiumPromotionPatch { public class PremiumPromotionPatch {
private static final boolean HIDE_PREMIUM_PROMOTION =
Settings.HIDE_PREMIUM_PROMOTION.get();
public static void hidePremiumPromotion(View view) { public static void hidePremiumPromotionBottomSheet(View view) {
if (!Settings.HIDE_PREMIUM_PROMOTION.get()) if (HIDE_PREMIUM_PROMOTION) {
return; view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
try {
if (!(view instanceof ViewGroup viewGroup)) {
return;
}
if (!(viewGroup.getChildAt(0) instanceof ViewGroup mealBarLayoutRoot)) {
return;
}
if (!(mealBarLayoutRoot.getChildAt(0) instanceof LinearLayout linearLayout)) {
return;
}
if (!(linearLayout.getChildAt(0) instanceof ImageView imageView)) {
return;
}
if (imageView.getVisibility() == View.VISIBLE) {
view.setVisibility(View.GONE);
}
} catch (Exception ex) {
Logger.printException(() -> "hidePremiumPromotionBottomSheet failure", ex);
}
});
}
}
view.getViewTreeObserver().addOnGlobalLayoutListener(() -> { public static void hidePremiumPromotionDialog(Dialog dialog, View contentView) {
try { if (HIDE_PREMIUM_PROMOTION) {
if (!(view instanceof ViewGroup viewGroup)) { disableDimBehind(dialog.getWindow());
return; dialog.setOnShowListener(DialogInterface::dismiss);
} if (BaseSettings.ENABLE_DEBUG_LOGGING.get()) {
if (!(viewGroup.getChildAt(0) instanceof ViewGroup mealBarLayoutRoot)) { Utils.showToastShort(str("revanced_hide_premium_promotion_closed_toast"));
return;
}
if (!(mealBarLayoutRoot.getChildAt(0) instanceof LinearLayout linearLayout)) {
return;
}
if (!(linearLayout.getChildAt(0) instanceof ImageView imageView)) {
return;
}
if (imageView.getVisibility() == View.VISIBLE) {
view.setVisibility(View.GONE);
}
} catch (Exception ex) {
Logger.printException(() -> "hideGetPremium failure", ex);
} }
}); } else {
dialog.setContentView(contentView);
}
} }
} }

View File

@ -2,6 +2,7 @@ package app.revanced.patches.music.ads.general
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.music.navigation.components.navigationBarComponentsPatch import app.revanced.patches.music.navigation.components.navigationBarComponentsPatch
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
@ -9,6 +10,8 @@ import app.revanced.patches.music.utils.extension.Constants.ADS_PATH
import app.revanced.patches.music.utils.extension.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.extension.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.navigation.navigationBarHookPatch import app.revanced.patches.music.utils.navigation.navigationBarHookPatch
import app.revanced.patches.music.utils.patch.PatchList.HIDE_ADS import app.revanced.patches.music.utils.patch.PatchList.HIDE_ADS
import app.revanced.patches.music.utils.playservice.is_7_28_or_greater
import app.revanced.patches.music.utils.playservice.versionCheckPatch
import app.revanced.patches.music.utils.resourceid.buttonContainer import app.revanced.patches.music.utils.resourceid.buttonContainer
import app.revanced.patches.music.utils.resourceid.floatingLayout import app.revanced.patches.music.utils.resourceid.floatingLayout
import app.revanced.patches.music.utils.resourceid.interstitialsContainer import app.revanced.patches.music.utils.resourceid.interstitialsContainer
@ -30,6 +33,7 @@ import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@ -58,6 +62,7 @@ val adsPatch = bytecodePatch(
navigationBarComponentsPatch, // for 'Hide upgrade button' setting navigationBarComponentsPatch, // for 'Hide upgrade button' setting
navigationBarHookPatch, navigationBarHookPatch,
sharedResourceIdPatch, sharedResourceIdPatch,
versionCheckPatch,
) )
execute { execute {
@ -78,16 +83,35 @@ val adsPatch = bytecodePatch(
// region patch for hide premium promotion popup // region patch for hide premium promotion popup
// get premium bottom sheet
floatingLayoutFingerprint.methodOrThrow().apply { floatingLayoutFingerprint.methodOrThrow().apply {
val targetIndex = indexOfFirstLiteralInstructionOrThrow(floatingLayout) + 2 val targetIndex = indexOfFirstLiteralInstructionOrThrow(floatingLayout) + 2
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
targetIndex + 1, targetIndex + 1,
"invoke-static {v$targetRegister}, $PREMIUM_PROMOTION_POP_UP_CLASS_DESCRIPTOR->hidePremiumPromotion(Landroid/view/View;)V" "invoke-static {v$targetRegister}, $PREMIUM_PROMOTION_POP_UP_CLASS_DESCRIPTOR->hidePremiumPromotionBottomSheet(Landroid/view/View;)V"
) )
} }
// get premium dialog in player
if (is_7_28_or_greater) {
getPremiumDialogFingerprint
.methodOrThrow(getPremiumDialogParentFingerprint)
.apply {
val setContentViewIndex = indexOfSetContentViewInstruction(this)
val dialogInstruction = getInstruction<FiveRegisterInstruction>(setContentViewIndex)
val dialogRegister = dialogInstruction.registerC
val viewRegister = dialogInstruction.registerD
replaceInstruction(
setContentViewIndex,
"invoke-static {v$dialogRegister, v$viewRegister}, " +
" $PREMIUM_PROMOTION_POP_UP_CLASS_DESCRIPTOR->hidePremiumPromotionDialog(Landroid/app/Dialog;Landroid/view/View;)V"
)
}
}
// endregion // endregion
// region patch for hide premium renewal banner // region patch for hide premium renewal banner

View File

@ -3,13 +3,18 @@ package app.revanced.patches.music.ads.general
import app.revanced.patches.music.utils.resourceid.buttonContainer import app.revanced.patches.music.utils.resourceid.buttonContainer
import app.revanced.patches.music.utils.resourceid.floatingLayout import app.revanced.patches.music.utils.resourceid.floatingLayout
import app.revanced.patches.music.utils.resourceid.interstitialsContainer import app.revanced.patches.music.utils.resourceid.interstitialsContainer
import app.revanced.patches.music.utils.resourceid.modernDialogBackground
import app.revanced.patches.music.utils.resourceid.musicNotifierShelf import app.revanced.patches.music.utils.resourceid.musicNotifierShelf
import app.revanced.patches.music.utils.resourceid.privacyTosFooter import app.revanced.patches.music.utils.resourceid.privacyTosFooter
import app.revanced.patches.music.utils.resourceid.slidingDialogAnimation import app.revanced.patches.music.utils.resourceid.slidingDialogAnimation
import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.or import app.revanced.util.or
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode 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 accountMenuFooterFingerprint = legacyFingerprint( internal val accountMenuFooterFingerprint = legacyFingerprint(
name = "accountMenuFooterFingerprint", name = "accountMenuFooterFingerprint",
@ -34,6 +39,29 @@ internal val floatingLayoutFingerprint = legacyFingerprint(
literals = listOf(floatingLayout) literals = listOf(floatingLayout)
) )
internal val getPremiumDialogParentFingerprint = legacyFingerprint(
name = "getPremiumDialogParentFingerprint",
returnType = "Landroid/graphics/drawable/Drawable;",
accessFlags = AccessFlags.PROTECTED.value,
parameters = listOf("Landroid/content/Context;"),
literals = listOf(modernDialogBackground)
)
internal val getPremiumDialogFingerprint = legacyFingerprint(
name = "getPremiumDialogFingerprint",
returnType = "Landroid/app/Dialog;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/os/Bundle;"),
customFingerprint = { method, _ ->
indexOfSetContentViewInstruction(method) >= 0
}
)
internal fun indexOfSetContentViewInstruction(method: Method) =
method.indexOfFirstInstruction {
getReference<MethodReference>()?.toString() == "Landroid/app/Dialog;->setContentView(Landroid/view/View;)V"
}
internal val getPremiumTextViewFingerprint = legacyFingerprint( internal val getPremiumTextViewFingerprint = legacyFingerprint(
name = "getPremiumTextViewFingerprint", name = "getPremiumTextViewFingerprint",
returnType = "V", returnType = "V",

View File

@ -31,6 +31,8 @@ var is_7_25_or_greater = false
private set private set
var is_7_27_or_greater = false var is_7_27_or_greater = false
private set private set
var is_7_28_or_greater = false
private set
var is_7_29_or_greater = false var is_7_29_or_greater = false
private set private set
var is_7_33_or_greater = false var is_7_33_or_greater = false
@ -65,6 +67,7 @@ val versionCheckPatch = resourcePatch(
is_7_23_or_greater = 244199000 <= playStoreServicesVersion is_7_23_or_greater = 244199000 <= playStoreServicesVersion
is_7_25_or_greater = 244399000 <= playStoreServicesVersion is_7_25_or_greater = 244399000 <= playStoreServicesVersion
is_7_27_or_greater = 244515000 <= playStoreServicesVersion is_7_27_or_greater = 244515000 <= playStoreServicesVersion
is_7_28_or_greater = 244699000 <= playStoreServicesVersion
is_7_29_or_greater = 244799000 <= playStoreServicesVersion is_7_29_or_greater = 244799000 <= playStoreServicesVersion
is_7_33_or_greater = 245199000 <= playStoreServicesVersion is_7_33_or_greater = 245199000 <= playStoreServicesVersion
is_8_03_or_greater = 250399000 <= playStoreServicesVersion is_8_03_or_greater = 250399000 <= playStoreServicesVersion

View File

@ -61,6 +61,8 @@ var miniPlayerPlayPauseReplayButton = -1L
private set private set
var miniPlayerViewPager = -1L var miniPlayerViewPager = -1L
private set private set
var modernDialogBackground = -1L
private set
var musicNotifierShelf = -1L var musicNotifierShelf = -1L
private set private set
var musicTasteBuilderShelf = -1L var musicTasteBuilderShelf = -1L
@ -208,6 +210,10 @@ internal val sharedResourceIdPatch = resourcePatch(
ID, ID,
"mini_player_view_pager" "mini_player_view_pager"
] ]
modernDialogBackground = resourceMappings[
DRAWABLE,
"modern_dialog_background"
]
musicNotifierShelf = resourceMappings[ musicNotifierShelf = resourceMappings[
LAYOUT, LAYOUT,
"music_notifier_shelf" "music_notifier_shelf"