mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-04-30 22:54:40 +02:00
fix(YouTube - Theme): Use custom seekbar color for cairo startup animation (#4399)
This commit is contained in:
parent
8891f98511
commit
1cba2948a6
@ -6,11 +6,19 @@ import android.content.res.Resources;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||||
|
|
||||||
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
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.shared.settings.BaseSettings;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -93,17 +101,6 @@ public final class SeekbarColorPatch {
|
|||||||
return customSeekbarColor;
|
return customSeekbarColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point
|
|
||||||
*/
|
|
||||||
public static boolean useLotteLaunchSplashScreen(boolean original) {
|
|
||||||
Logger.printDebug(() -> "useLotteLaunchSplashScreen original: " + original);
|
|
||||||
|
|
||||||
if (SEEKBAR_CUSTOM_COLOR_ENABLED) return false;
|
|
||||||
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int colorChannelTo3Bits(int channel8Bits) {
|
private static int colorChannelTo3Bits(int channel8Bits) {
|
||||||
final float channel3Bits = channel8Bits * 7 / 255f;
|
final float channel3Bits = channel8Bits * 7 / 255f;
|
||||||
|
|
||||||
@ -127,6 +124,17 @@ public final class SeekbarColorPatch {
|
|||||||
/**
|
/**
|
||||||
* Injection point
|
* Injection point
|
||||||
*/
|
*/
|
||||||
|
public static boolean useLotteLaunchSplashScreen(boolean original) {
|
||||||
|
// This method is only used for development purposes to force the old style launch screen.
|
||||||
|
// Forcing this off on some devices can cause unexplained startup crashes,
|
||||||
|
// where the lottie animation is still used even though this condition appears to bypass it.
|
||||||
|
return original; // false = drawable style, true = lottie style.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
* Old drawable style launch screen.
|
||||||
|
*/
|
||||||
public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) {
|
public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) {
|
||||||
// Alternatively a ColorMatrixColorFilter can be used to change the color of the drawable
|
// 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
|
// without using any styles, but a color filter cannot selectively change the seekbar
|
||||||
@ -134,6 +142,8 @@ public final class SeekbarColorPatch {
|
|||||||
// Even if the seekbar color xml value is changed to a completely different color (such as green),
|
// 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.
|
// a color filter still cannot be selectively applied when the drawable has more than 1 color.
|
||||||
try {
|
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);
|
String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor);
|
||||||
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
|
||||||
|
|
||||||
@ -154,6 +164,77 @@ public final class SeekbarColorPatch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
* Modern Lottie style animation.
|
||||||
|
*/
|
||||||
|
public static void setSplashAnimationLottie(LottieAnimationView view, int resourceId) {
|
||||||
|
try {
|
||||||
|
if (!SEEKBAR_CUSTOM_COLOR_ENABLED) {
|
||||||
|
view.patch_setAnimation(resourceId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if (false) { // Set true to force slow animation for development.
|
||||||
|
final int longAnimation = Utils.getResourceIdentifier(
|
||||||
|
Utils.isDarkModeEnabled(Utils.getContext())
|
||||||
|
? "startup_animation_5s_30fps_dark"
|
||||||
|
: "startup_animation_5s_30fps_light",
|
||||||
|
"raw");
|
||||||
|
if (longAnimation != 0) {
|
||||||
|
resourceId = longAnimation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must specify primary key name otherwise the morphing YT logo color is also changed.
|
||||||
|
String originalKey = "\"k\":";
|
||||||
|
String originalPrimary = originalKey + "[1,0,0.2,1]";
|
||||||
|
String originalAccent = originalKey + "[1,0.152941176471,0.56862745098,1]";
|
||||||
|
|
||||||
|
String replacementPrimary = originalKey + getColorStringArray(customSeekbarColor);
|
||||||
|
String replacementAccent = originalKey + getColorStringArray(customSeekbarColorGradient[1]);
|
||||||
|
|
||||||
|
String json = loadRawResourceAsString(resourceId);
|
||||||
|
if (json == null) {
|
||||||
|
return; // Should never happen.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BaseSettings.DEBUG.get() && (!json.contains(originalPrimary) || !json.contains(originalAccent))) {
|
||||||
|
String jsonFinal = json;
|
||||||
|
Logger.printException(() -> "Could not replace launch animation colors: " + jsonFinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.printDebug(() -> "Replacing Lottie animation JSON");
|
||||||
|
json = json.replace(originalPrimary, replacementPrimary);
|
||||||
|
json = json.replace(originalAccent, replacementAccent);
|
||||||
|
|
||||||
|
// cacheKey is not needed since the animation will not be reused.
|
||||||
|
view.patch_setAnimation(new ByteArrayInputStream(json.getBytes()), null);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "setSplashAnimationLottie failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getColorStringArray(int color) {
|
||||||
|
return Arrays.toString(new double[]{
|
||||||
|
Color.red(color) / 255.0,
|
||||||
|
Color.green(color) / 255.0,
|
||||||
|
Color.blue(color) / 255.0,
|
||||||
|
Color.alpha(color) / 255.0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String loadRawResourceAsString(int resourceId) {
|
||||||
|
try (InputStream inputStream = Utils.getContext().getResources().openRawResource(resourceId);
|
||||||
|
Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name()).useDelimiter("\\A")) {
|
||||||
|
return scanner.next();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.printException(() -> "Could not load resource: " + resourceId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.airbnb.lottie;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class LottieAnimationView {
|
||||||
|
|
||||||
|
public void patch_setAnimation(InputStream stream, String cacheKey) {
|
||||||
|
throw new RuntimeException("stub");
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void patch_setAnimation(int rawResInt) {
|
||||||
|
throw new RuntimeException("stub");
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,12 @@ package app.revanced.patches.youtube.layout.seekbar
|
|||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
import app.revanced.util.containsLiteralInstruction
|
import app.revanced.util.containsLiteralInstruction
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.literal
|
import app.revanced.util.literal
|
||||||
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.reference.MethodReference
|
||||||
|
|
||||||
internal val fullscreenSeekbarThumbnailsFingerprint = fingerprint {
|
internal val fullscreenSeekbarThumbnailsFingerprint = fingerprint {
|
||||||
returns("Z")
|
returns("Z")
|
||||||
@ -109,3 +112,52 @@ internal val launchScreenLayoutTypeFingerprint = fingerprint {
|
|||||||
&& method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag)
|
&& method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const val LOTTIE_ANIMATION_VIEW_CLASS_TYPE = "Lcom/airbnb/lottie/LottieAnimationView;"
|
||||||
|
|
||||||
|
internal val lottieAnimationViewSetAnimationIntFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameters("I")
|
||||||
|
returns("V")
|
||||||
|
custom { methodDef, classDef ->
|
||||||
|
classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE && methodDef.indexOfFirstInstruction {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Lcom/airbnb/lottie/LottieAnimationView;"
|
||||||
|
&& reference.name == "isInEditMode"
|
||||||
|
} >= 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val lottieAnimationViewSetAnimationStreamFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameters("L")
|
||||||
|
returns("V")
|
||||||
|
custom { methodDef, classDef ->
|
||||||
|
classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE && methodDef.indexOfFirstInstruction {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Ljava/util/Set;"
|
||||||
|
&& reference.name == "add"
|
||||||
|
} >= 0 && methodDef.containsLiteralInstruction(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val lottieCompositionFactoryZipFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
|
parameters("Landroid/content/Context;", "Ljava/lang/String;", "Ljava/lang/String;")
|
||||||
|
returns("L")
|
||||||
|
strings(".zip", ".lottie")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves using class found in [lottieCompositionFactoryZipFingerprint].
|
||||||
|
*
|
||||||
|
* [Original method](https://github.com/airbnb/lottie-android/blob/26ad8bab274eac3f93dccccfa0cafc39f7408d13/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java#L386)
|
||||||
|
*/
|
||||||
|
internal val lottieCompositionFactoryFromJsonInputStreamFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
|
parameters("Ljava/io/InputStream;", "Ljava/lang/String;")
|
||||||
|
returns("L")
|
||||||
|
literal { 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@ package app.revanced.patches.youtube.layout.seekbar
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
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.patch.PatchException
|
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
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||||
import app.revanced.patches.shared.misc.mapping.get
|
import app.revanced.patches.shared.misc.mapping.get
|
||||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||||
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
import app.revanced.patches.shared.misc.mapping.resourceMappings
|
||||||
@ -22,15 +24,21 @@ 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.copyXmlNode
|
||||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||||
|
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.indexOfFirstLiteralInstructionOrThrow
|
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||||
import app.revanced.util.inputStreamFromBundledResource
|
import app.revanced.util.inputStreamFromBundledResource
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertFeatureFlagBooleanOverride
|
||||||
|
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.builder.MutableMethodImplementation
|
||||||
|
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.TwoRegisterInstruction
|
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.ImmutableMethodParameter
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import kotlin.use
|
import kotlin.use
|
||||||
@ -307,7 +315,11 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
|
|
||||||
// region apply seekbar custom color to splash screen animation.
|
// region apply seekbar custom color to splash screen animation.
|
||||||
|
|
||||||
// Don't use the lotte splash screen layout if using custom seekbar.
|
if (!is_19_34_or_greater) {
|
||||||
|
return@execute // 19.25 does not have a cairo launch animation.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add development hook to force old drawable splash animation.
|
||||||
arrayOf(
|
arrayOf(
|
||||||
launchScreenLayoutTypeFingerprint,
|
launchScreenLayoutTypeFingerprint,
|
||||||
mainActivityOnCreateFingerprint
|
mainActivityOnCreateFingerprint
|
||||||
@ -318,7 +330,7 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook the splash animation drawable to set the a seekbar color theme.
|
// Hook the splash animation to set the a seekbar color.
|
||||||
mainActivityOnCreateFingerprint.method.apply {
|
mainActivityOnCreateFingerprint.method.apply {
|
||||||
val drawableIndex = indexOfFirstInstructionOrThrow {
|
val drawableIndex = indexOfFirstInstructionOrThrow {
|
||||||
val reference = getReference<MethodReference>()
|
val reference = getReference<MethodReference>()
|
||||||
@ -333,6 +345,87 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
"invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
"invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
"setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V"
|
"setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Replace the Lottie animation view setAnimation(int) call.
|
||||||
|
val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name
|
||||||
|
|
||||||
|
findInstructionIndicesReversedOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Lcom/airbnb/lottie/LottieAnimationView;"
|
||||||
|
&& reference.name == setAnimationIntMethodName
|
||||||
|
}.forEach { index ->
|
||||||
|
val instruction = getInstruction<FiveRegisterInstruction>(index)
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
index,
|
||||||
|
"invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " +
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie" +
|
||||||
|
"(Lcom/airbnb/lottie/LottieAnimationView;I)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add non obfuscated method aliases for `setAnimation(int)`
|
||||||
|
// and `setAnimation(InputStream, String)` so extension code can call them.
|
||||||
|
lottieAnimationViewSetAnimationIntFingerprint.classDef.methods.apply {
|
||||||
|
val addedMethodName = "patch_setAnimation"
|
||||||
|
val setAnimationIntName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name
|
||||||
|
|
||||||
|
add(ImmutableMethod(
|
||||||
|
LOTTIE_ANIMATION_VIEW_CLASS_TYPE,
|
||||||
|
addedMethodName,
|
||||||
|
listOf(ImmutableMethodParameter("I", null, null)),
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC.value,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
MutableMethodImplementation(2),
|
||||||
|
).toMutable().apply {
|
||||||
|
addInstructions(
|
||||||
|
"""
|
||||||
|
invoke-virtual { p0, p1 }, Lcom/airbnb/lottie/LottieAnimationView;->$setAnimationIntName(I)V
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
val factoryStreamClass : CharSequence
|
||||||
|
val factoryStreamName : CharSequence
|
||||||
|
val factoryStreamReturnType : CharSequence
|
||||||
|
lottieCompositionFactoryFromJsonInputStreamFingerprint.match(
|
||||||
|
lottieCompositionFactoryZipFingerprint.originalClassDef
|
||||||
|
).originalMethod.apply {
|
||||||
|
factoryStreamClass = definingClass
|
||||||
|
factoryStreamName = name
|
||||||
|
factoryStreamReturnType = returnType
|
||||||
|
}
|
||||||
|
|
||||||
|
val setAnimationStreamName = lottieAnimationViewSetAnimationStreamFingerprint
|
||||||
|
.originalMethod.name
|
||||||
|
|
||||||
|
add(ImmutableMethod(
|
||||||
|
LOTTIE_ANIMATION_VIEW_CLASS_TYPE,
|
||||||
|
addedMethodName,
|
||||||
|
listOf(
|
||||||
|
ImmutableMethodParameter("Ljava/io/InputStream;", null, null),
|
||||||
|
ImmutableMethodParameter("Ljava/lang/String;", null, null)
|
||||||
|
),
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC.value,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
MutableMethodImplementation(4),
|
||||||
|
).toMutable().apply {
|
||||||
|
addInstructions(
|
||||||
|
"""
|
||||||
|
invoke-static { p1, p2 }, $factoryStreamClass->$factoryStreamName(Ljava/io/InputStream;Ljava/lang/String;)$factoryStreamReturnType
|
||||||
|
move-result-object v0
|
||||||
|
invoke-virtual { p0, v0}, Lcom/airbnb/lottie/LottieAnimationView;->$setAnimationStreamName($factoryStreamReturnType)V
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user