fix(YouTube - Hide layout components): Show correct custom header logo if 'Hide YouTube Doodles' is enabled (#5431)

This commit is contained in:
LisoUseInAIKyrios
2025-07-12 18:34:29 +04:00
committed by GitHub
parent 2b93ff6cfc
commit 19bc5b63c5
4 changed files with 92 additions and 34 deletions

View File

@@ -1,9 +1,12 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
@@ -11,18 +14,21 @@ import app.revanced.extension.youtube.settings.Settings;
public class ChangeHeaderPatch { public class ChangeHeaderPatch {
public enum HeaderLogo { public enum HeaderLogo {
DEFAULT(null), DEFAULT(null, null),
REGULAR("ytWordmarkHeader"), REGULAR("ytWordmarkHeader", "yt_ringo2_wordmark_header"),
PREMIUM("ytPremiumWordmarkHeader"), PREMIUM("ytPremiumWordmarkHeader", "yt_ringo2_premium_wordmark_header"),
REVANCED("revanced_header_logo"), REVANCED("revanced_header_logo", "revanced_header_logo"),
REVANCED_MINIMAL("revanced_header_logo_minimal"), REVANCED_MINIMAL("revanced_header_logo_minimal", "revanced_header_logo_minimal"),
CUSTOM("custom_header"); CUSTOM("custom_header", "custom_header");
@Nullable @Nullable
private final String resourceName; private final String attributeName;
@Nullable
private final String drawableName;
HeaderLogo(@Nullable String resourceName) { HeaderLogo(@Nullable String attributeName, @Nullable String drawableName) {
this.resourceName = resourceName; this.attributeName = attributeName;
this.drawableName = drawableName;
} }
/** /**
@@ -30,24 +36,66 @@ public class ChangeHeaderPatch {
*/ */
@Nullable @Nullable
private Integer getAttributeId() { private Integer getAttributeId() {
if (resourceName == null) { if (attributeName == null) {
return null; return null;
} }
final int identifier = Utils.getResourceIdentifier(resourceName, "attr"); final int identifier = Utils.getResourceIdentifier(attributeName, "attr");
// Identifier is zero if custom header setting was included in imported settings if (identifier == 0) {
// and a custom image was not included during patching. // Identifier is zero if custom header setting was included in imported settings
return identifier == 0 ? null : identifier; // and a custom image was not included during patching.
Logger.printDebug(() -> "Could not find attribute: " + drawableName);
Settings.HEADER_LOGO.resetToDefault();
return null;
}
return identifier;
}
@Nullable
public Drawable getDrawable() {
if (drawableName == null) {
return null;
}
String drawableFullName = drawableName + (Utils.isDarkModeEnabled()
? "_dark"
: "_light");
final int identifier = Utils.getResourceIdentifier(drawableFullName, "drawable");
if (identifier == 0) {
Logger.printDebug(() -> "Could not find drawable: " + drawableFullName);
Settings.HEADER_LOGO.resetToDefault();
return null;
}
return Utils.getContext().getDrawable(identifier);
} }
} }
@Nullable
private static final Integer headerLogoResource = Settings.HEADER_LOGO.get().getAttributeId();
/** /**
* Injection point. * Injection point.
*/ */
public static int getHeaderAttributeId(int original) { public static int getHeaderAttributeId(int original) {
return Objects.requireNonNullElse(headerLogoResource, original); return Objects.requireNonNullElse(Settings.HEADER_LOGO.get().getAttributeId(), original);
}
public static Drawable getDrawable(Drawable original) {
Drawable logo = Settings.HEADER_LOGO.get().getDrawable();
if (logo != null) {
return logo;
}
// TODO: If 'Hide Doodles' is enabled, this will force the regular logo regardless
// what account the user has. This can be improved the next time a Doodle is
// active and the attribute id is passed to this method so the correct
// regular/premium logo is returned.
logo = HeaderLogo.REGULAR.getDrawable();
if (logo != null) {
return logo;
}
// Should never happen.
Logger.printException(() -> "Could not find regular header logo resource");
return original;
} }
} }

View File

@@ -4,12 +4,14 @@ import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButt
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.StringTrieSearch; import app.revanced.extension.youtube.StringTrieSearch;
import app.revanced.extension.youtube.patches.ChangeHeaderPatch;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.NavigationBar; import app.revanced.extension.youtube.shared.NavigationBar;
import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.PlayerType;
@@ -437,13 +439,11 @@ public final class LayoutComponentsFilter extends Filter {
/** /**
* Injection point. * Injection point.
*/ */
@Nullable public static void setDoodleDrawable(ImageView imageView, Drawable original) {
public static Drawable hideYoodles(Drawable animatedYoodle) { Drawable replacement = HIDE_DOODLES_ENABLED
if (HIDE_DOODLES_ENABLED) { ? ChangeHeaderPatch.getDrawable(original)
return null; : original;
} imageView.setImageDrawable(replacement);
return animatedYoodle;
} }
private static final boolean HIDE_SHOW_MORE_BUTTON_ENABLED = Settings.HIDE_SHOW_MORE_BUTTON.get(); private static final boolean HIDE_SHOW_MORE_BUTTON_ENABLED = Settings.HIDE_SHOW_MORE_BUTTON.get();

View File

@@ -22,6 +22,8 @@ import app.revanced.util.forEachLiteralValueInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import java.io.File import java.io.File
private val variants = arrayOf("light", "dark")
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/ChangeHeaderPatch;" "Lapp/revanced/extension/youtube/patches/ChangeHeaderPatch;"
@@ -29,6 +31,17 @@ private val changeHeaderBytecodePatch = bytecodePatch {
dependsOn(resourceMappingPatch) dependsOn(resourceMappingPatch)
execute { execute {
// Resources are not used during patching, but extension code uses these
// images so verify they exist.
arrayOf(
"yt_ringo2_wordmark_header",
"yt_ringo2_premium_wordmark_header"
).forEach { resource ->
variants.forEach { theme ->
resourceMappings["drawable", resource + "_" + theme]
}
}
arrayOf( arrayOf(
"ytWordmarkHeader", "ytWordmarkHeader",
"ytPremiumWordmarkHeader" "ytPremiumWordmarkHeader"
@@ -57,7 +70,6 @@ private val targetResourceDirectoryNames = mapOf(
"mdpi" to "129px x 48px" "mdpi" to "129px x 48px"
).mapKeys { (dpi, _) -> "drawable-$dpi" } ).mapKeys { (dpi, _) -> "drawable-$dpi" }
private val variants = arrayOf("light", "dark")
/** /**
* Header logos built into this patch. * Header logos built into this patch.

View File

@@ -8,6 +8,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.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
@@ -379,16 +380,13 @@ val hideLayoutComponentsPatch = bytecodePatch(
findInstructionIndicesReversedOrThrow { findInstructionIndicesReversedOrThrow {
getReference<MethodReference>()?.name == "setImageDrawable" getReference<MethodReference>()?.name == "setImageDrawable"
}.forEach { insertIndex -> }.forEach { insertIndex ->
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD val drawableRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
val imageViewRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
addInstructionsWithLabels( replaceInstruction(
insertIndex, insertIndex,
""" "invoke-static { v$imageViewRegister, v$drawableRegister }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->" +
invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideYoodles(Landroid/graphics/drawable/Drawable;)Landroid/graphics/drawable/Drawable; "setDoodleDrawable(Landroid/widget/ImageView;Landroid/graphics/drawable/Drawable;)V"
move-result-object v$register
if-eqz v$register, :hide
""",
ExternalLabel("hide", getInstruction(insertIndex + 1)),
) )
} }
} }