refactor(YouTube - Seekbar): Remove obsolete splash screen color code
This commit is contained in:
-51
@@ -1,51 +0,0 @@
|
|||||||
package app.revanced.extension.youtube.patches.theme;
|
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.ColorFilter;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.PixelFormat;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import app.revanced.extension.youtube.patches.HideSeekbarPatch;
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by {@link SeekbarColorPatch} change the color of the seekbar.
|
|
||||||
* and {@link HideSeekbarPatch} to hide the seekbar of the feed and watch history.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class ProgressBarDrawable extends Drawable {
|
|
||||||
|
|
||||||
private final Paint paint = new Paint();
|
|
||||||
{
|
|
||||||
paint.setColor(SeekbarColorPatch.getSeekbarColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(@NonNull Canvas canvas) {
|
|
||||||
if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.drawRect(getBounds(), paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAlpha(int alpha) {
|
|
||||||
paint.setAlpha(alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
|
||||||
paint.setColorFilter(colorFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOpacity() {
|
|
||||||
return PixelFormat.TRANSLUCENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-54
@@ -4,9 +4,7 @@ import static app.revanced.extension.shared.StringRef.str;
|
|||||||
import static app.revanced.extension.shared.Utils.clamp;
|
import static app.revanced.extension.shared.Utils.clamp;
|
||||||
import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle;
|
import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
|
||||||
|
|
||||||
import com.airbnb.lottie.LottieAnimationView;
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
|
||||||
@@ -15,7 +13,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
@@ -104,27 +101,6 @@ public final class SeekbarColorPatch {
|
|||||||
return customSeekbarColor;
|
return customSeekbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int colorChannelTo3Bits(int channel8Bits) {
|
|
||||||
final float channel3Bits = channel8Bits * 7 / 255f;
|
|
||||||
|
|
||||||
// If a color channel is near zero, then allow rounding up so values between
|
|
||||||
// 0x12 and 0x23 will show as 0x24. But always round down when the channel is
|
|
||||||
// near full saturation, otherwise rounding to nearest will cause all values
|
|
||||||
// between 0xEC and 0xFE to always show as full saturation (0xFF).
|
|
||||||
return channel3Bits < 6
|
|
||||||
? Math.round(channel3Bits)
|
|
||||||
: (int) channel3Bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
|
||||||
private static String get9BitStyleIdentifier(int color24Bit) {
|
|
||||||
final int r3 = colorChannelTo3Bits(Color.red(color24Bit));
|
|
||||||
final int g3 = colorChannelTo3Bits(Color.green(color24Bit));
|
|
||||||
final int b3 = colorChannelTo3Bits(Color.blue(color24Bit));
|
|
||||||
|
|
||||||
return String.format(Locale.US, "splash_seekbar_color_style_%d_%d_%d", r3, g3, b3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* injection point.
|
* injection point.
|
||||||
*/
|
*/
|
||||||
@@ -135,36 +111,6 @@ public final class SeekbarColorPatch {
|
|||||||
return original; // false = drawable style, true = lottie style.
|
return original; // false = drawable style, true = lottie style.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
* Old drawable style launch screen.
|
|
||||||
*/
|
|
||||||
public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) {
|
|
||||||
// Alternatively a ColorMatrixColorFilter can be used to change the color of the drawable
|
|
||||||
// without using any styles, but a color filter cannot selectively change the seekbar
|
|
||||||
// while keeping the red YT logo untouched.
|
|
||||||
// Even if the seekbar color xml value is changed to a completely different color (such as green),
|
|
||||||
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
|
|
||||||
try {
|
|
||||||
// Must set the color even if custom seekbar is off,
|
|
||||||
// because the xml color was replaced with a themed value.
|
|
||||||
String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor);
|
|
||||||
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
|
||||||
|
|
||||||
final int styleIdentifierDefault = Utils.getResourceIdentifierOrThrow(
|
|
||||||
seekbarStyle,
|
|
||||||
"style"
|
|
||||||
);
|
|
||||||
|
|
||||||
Resources.Theme theme = Utils.getContext().getResources().newTheme();
|
|
||||||
theme.applyStyle(styleIdentifierDefault, true);
|
|
||||||
|
|
||||||
vectorDrawable.applyTheme(theme);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "setSplashAnimationDrawableTheme failure", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
* Modern Lottie style animation.
|
* Modern Lottie style animation.
|
||||||
|
|||||||
+1
-134
@@ -1,11 +1,9 @@
|
|||||||
package app.revanced.patches.youtube.layout.seekbar
|
package app.revanced.patches.youtube.layout.seekbar
|
||||||
|
|
||||||
import app.revanced.patcher.Fingerprint
|
import app.revanced.patcher.Fingerprint
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
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.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
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.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
@@ -17,17 +15,13 @@ import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
|||||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
import app.revanced.util.copyXmlNode
|
|
||||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
|
||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.inputStreamFromBundledResource
|
|
||||||
import app.revanced.util.insertLiteralOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
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
|
||||||
@@ -38,9 +32,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||||
import org.w3c.dom.Element
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import kotlin.use
|
|
||||||
|
|
||||||
internal var reelTimeBarPlayedColorId = -1L
|
internal var reelTimeBarPlayedColorId = -1L
|
||||||
private set
|
private set
|
||||||
@@ -57,8 +48,6 @@ internal var ytTextSecondaryId = -1L
|
|||||||
internal var inlineTimeBarLiveSeekableRangeId = -1L
|
internal var inlineTimeBarLiveSeekableRangeId = -1L
|
||||||
private set
|
private set
|
||||||
|
|
||||||
internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color"
|
|
||||||
|
|
||||||
private val seekbarColorResourcePatch = resourcePatch {
|
private val seekbarColorResourcePatch = resourcePatch {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
@@ -92,21 +81,6 @@ private val seekbarColorResourcePatch = resourcePatch {
|
|||||||
"inline_time_bar_live_seekable_range"
|
"inline_time_bar_live_seekable_range"
|
||||||
]
|
]
|
||||||
|
|
||||||
// Modify the resume playback drawable and replace the progress bar with a custom drawable.
|
|
||||||
document("res/drawable/resume_playback_progressbar_drawable.xml").use { document ->
|
|
||||||
val layerList = document.getElementsByTagName("layer-list").item(0) as Element
|
|
||||||
val progressNode = layerList.getElementsByTagName("item").item(1) as Element
|
|
||||||
if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) {
|
|
||||||
throw PatchException("Could not find progress bar")
|
|
||||||
}
|
|
||||||
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
|
|
||||||
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
|
|
||||||
val replacementNode = document.createElement(
|
|
||||||
"app.revanced.extension.youtube.patches.theme.ProgressBarDrawable",
|
|
||||||
)
|
|
||||||
scaleNode.replaceChild(replacementNode, shapeNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
ytYoutubeMagentaColorId = resourceMappings[
|
ytYoutubeMagentaColorId = resourceMappings[
|
||||||
"color",
|
"color",
|
||||||
"yt_youtube_magenta",
|
"yt_youtube_magenta",
|
||||||
@@ -115,99 +89,9 @@ private val seekbarColorResourcePatch = resourcePatch {
|
|||||||
"attr",
|
"attr",
|
||||||
"ytStaticBrandRed",
|
"ytStaticBrandRed",
|
||||||
]
|
]
|
||||||
|
|
||||||
// Add attribute and styles for splash screen custom color.
|
|
||||||
// Using a style is the only way to selectively change just the seekbar fill color.
|
|
||||||
//
|
|
||||||
// Because the style colors must be hard coded for all color possibilities,
|
|
||||||
// instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel)
|
|
||||||
// and the style color closest to the users custom color is used for the splash screen.
|
|
||||||
arrayOf(
|
|
||||||
inputStreamFromBundledResource("seekbar/values", "attrs.xml")!! to "res/values/attrs.xml",
|
|
||||||
ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml"
|
|
||||||
).forEach { (source, destination) ->
|
|
||||||
"resources".copyXmlNode(
|
|
||||||
document(source),
|
|
||||||
document(destination),
|
|
||||||
).close()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSplashDrawablePathFillColor(xmlFileNames: Iterable<String>, vararg resourceNames: String) {
|
|
||||||
xmlFileNames.forEach { xmlFileName ->
|
|
||||||
document(xmlFileName).use { document ->
|
|
||||||
val childNodes = document.childNodes
|
|
||||||
|
|
||||||
resourceNames.forEach { elementId ->
|
|
||||||
val element = childNodes.findElementByAttributeValueOrThrow(
|
|
||||||
"android:name",
|
|
||||||
elementId
|
|
||||||
)
|
|
||||||
|
|
||||||
val attribute = "android:fillColor"
|
|
||||||
if (!element.hasAttribute(attribute)) {
|
|
||||||
throw PatchException("Could not find $attribute for $elementId")
|
|
||||||
}
|
|
||||||
|
|
||||||
element.setAttribute(attribute, "?attr/$splashSeekbarColorAttributeName")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setSplashDrawablePathFillColor(
|
|
||||||
listOf(
|
|
||||||
"res/drawable/\$startup_animation_light__0.xml",
|
|
||||||
"res/drawable/\$startup_animation_dark__0.xml"
|
|
||||||
),
|
|
||||||
"_R_G_L_10_G_D_0_P_0"
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!is_19_46_or_greater) {
|
|
||||||
// Resources removed in 19.46+
|
|
||||||
setSplashDrawablePathFillColor(
|
|
||||||
listOf(
|
|
||||||
"res/drawable/\$buenos_aires_animation_light__0.xml",
|
|
||||||
"res/drawable/\$buenos_aires_animation_dark__0.xml"
|
|
||||||
),
|
|
||||||
"_R_G_L_8_G_D_0_P_0"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a style xml with all combinations of 9-bit colors.
|
|
||||||
*/
|
|
||||||
private fun create9BitSeekbarColorStyles(): String = StringBuilder().apply {
|
|
||||||
append("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
|
|
||||||
append("<resources>\n")
|
|
||||||
|
|
||||||
for (red in 0..7) {
|
|
||||||
for (green in 0..7) {
|
|
||||||
for (blue in 0..7) {
|
|
||||||
val name = "${red}_${green}_${blue}"
|
|
||||||
|
|
||||||
fun roundTo3BitHex(channel8Bits: Int) =
|
|
||||||
(channel8Bits * 255 / 7).toString(16).padStart(2, '0')
|
|
||||||
val r = roundTo3BitHex(red)
|
|
||||||
val g = roundTo3BitHex(green)
|
|
||||||
val b = roundTo3BitHex(blue)
|
|
||||||
val color = "#ff$r$g$b"
|
|
||||||
|
|
||||||
append(
|
|
||||||
"""
|
|
||||||
<style name="splash_seekbar_color_style_$name">
|
|
||||||
<item name="$splashSeekbarColorAttributeName">$color</item>
|
|
||||||
</style>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
append("</resources>")
|
|
||||||
}.toString()
|
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;"
|
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;"
|
||||||
|
|
||||||
val seekbarColorPatch = bytecodePatch(
|
val seekbarColorPatch = bytecodePatch(
|
||||||
@@ -344,21 +228,6 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Hook the splash animation to set the a seekbar color.
|
// Hook the splash animation to set the a seekbar color.
|
||||||
mainActivityOnCreateFingerprint.method.apply {
|
mainActivityOnCreateFingerprint.method.apply {
|
||||||
val drawableIndex = indexOfFirstInstructionOrThrow {
|
|
||||||
val reference = getReference<MethodReference>()
|
|
||||||
reference?.definingClass == "Landroid/widget/ImageView;"
|
|
||||||
&& reference.name == "getDrawable"
|
|
||||||
}
|
|
||||||
val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST)
|
|
||||||
val drawableRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
checkCastIndex + 1,
|
|
||||||
"invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
|
||||||
"setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Replace the Lottie animation view setAnimation(int) call.
|
|
||||||
val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name
|
val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name
|
||||||
|
|
||||||
findInstructionIndicesReversedOrThrow {
|
findInstructionIndicesReversedOrThrow {
|
||||||
@@ -371,13 +240,11 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
index,
|
index,
|
||||||
"invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " +
|
"invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " +
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie" +
|
"$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie(Lcom/airbnb/lottie/LottieAnimationView;I)V"
|
||||||
"(Lcom/airbnb/lottie/LottieAnimationView;I)V"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add non obfuscated method aliases for `setAnimation(int)`
|
// Add non obfuscated method aliases for `setAnimation(int)`
|
||||||
// and `setAnimation(InputStream, String)` so extension code can call them.
|
// and `setAnimation(InputStream, String)` so extension code can call them.
|
||||||
lottieAnimationViewSetAnimationIntFingerprint.classDef.methods.apply {
|
lottieAnimationViewSetAnimationIntFingerprint.classDef.methods.apply {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<attr format="reference|color" name="splash_custom_seekbar_color"/>
|
|
||||||
</resources>
|
|
||||||
Reference in New Issue
Block a user