mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-05-01 15:14:27 +02:00
feat(YouTube - Miniplayer): Add horizontal drag gesture (#3859)
This commit is contained in:
parent
e377b1e6ad
commit
e32b19e170
@ -10,12 +10,44 @@ import app.revanced.extension.shared.settings.BaseSettings;
|
|||||||
public final class EnableDebuggingPatch {
|
public final class EnableDebuggingPatch {
|
||||||
|
|
||||||
private static final ConcurrentMap<Long, Boolean> featureFlags
|
private static final ConcurrentMap<Long, Boolean> featureFlags
|
||||||
= new ConcurrentHashMap<>(150, 0.75f, 1);
|
= new ConcurrentHashMap<>(300, 0.75f, 1);
|
||||||
|
|
||||||
public static boolean isFeatureFlagEnabled(long flag, boolean value) {
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
|
||||||
if (value && BaseSettings.DEBUG.get()) {
|
if (value && BaseSettings.DEBUG.get()) {
|
||||||
if (featureFlags.putIfAbsent(flag, true) == null) {
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
Logger.printDebug(() -> "feature is enabled: " + flag);
|
Logger.printDebug(() -> "boolean feature is enabled: " + flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) {
|
||||||
|
if (defaultValue != value && BaseSettings.DEBUG.get()) {
|
||||||
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
|
// Align the log outputs to make post processing easier.
|
||||||
|
Logger.printDebug(() -> " double feature is enabled: " + flag
|
||||||
|
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) {
|
||||||
|
if (defaultValue != value && BaseSettings.DEBUG.get()) {
|
||||||
|
if (featureFlags.putIfAbsent(flag, true) == null) {
|
||||||
|
Logger.printDebug(() -> " long feature is enabled: " + flag
|
||||||
|
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ public final class MiniplayerPatch {
|
|||||||
private static final boolean MINIPLAYER_ROUNDED_CORNERS_ENABLED =
|
private static final boolean MINIPLAYER_ROUNDED_CORNERS_ENABLED =
|
||||||
Settings.MINIPLAYER_ROUNDED_CORNERS.get();
|
Settings.MINIPLAYER_ROUNDED_CORNERS.get();
|
||||||
|
|
||||||
|
private static final boolean MINIPLAYER_HORIZONTAL_DRAG_ENABLED =
|
||||||
|
DRAG_AND_DROP_ENABLED && Settings.MINIPLAYER_HORIZONTAL_DRAG.get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a broken and always present subtitle text that is only
|
* Remove a broken and always present subtitle text that is only
|
||||||
* present with {@link MiniplayerType#MODERN_2}. Bug was fixed in 19.21.
|
* present with {@link MiniplayerType#MODERN_2}. Bug was fixed in 19.21.
|
||||||
@ -131,6 +134,13 @@ public final class MiniplayerPatch {
|
|||||||
|
|
||||||
private static final int OPACITY_LEVEL;
|
private static final int OPACITY_LEVEL;
|
||||||
|
|
||||||
|
public static final class MiniplayerHorizontalDragAvailability implements Setting.Availability {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return Settings.MINIPLAYER_TYPE.get().isModern() && Settings.MINIPLAYER_DRAG_AND_DROP.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final class MiniplayerHideExpandCloseAvailability implements Setting.Availability {
|
public static final class MiniplayerHideExpandCloseAvailability implements Setting.Availability {
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
@ -248,21 +258,15 @@ public final class MiniplayerPatch {
|
|||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static float setMovementBoundFactor(float original) {
|
|
||||||
// Not clear if customizing this is useful or not.
|
|
||||||
// So for now just log this and use the original value.
|
|
||||||
if (original != 1.0) Logger.printDebug(() -> "setMovementBoundFactor original: " + original);
|
|
||||||
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static boolean setDropShadow(boolean original) {
|
public static boolean setHorizontalDrag(boolean original) {
|
||||||
|
if (CURRENT_TYPE.isModern()) {
|
||||||
|
return MINIPLAYER_HORIZONTAL_DRAG_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import static java.lang.Boolean.TRUE;
|
|||||||
import static app.revanced.extension.shared.settings.Setting.*;
|
import static app.revanced.extension.shared.settings.Setting.*;
|
||||||
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
|
||||||
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
|
||||||
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
||||||
@ -138,6 +139,7 @@ public class Settings extends BaseSettings {
|
|||||||
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
|
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
|
||||||
public static final BooleanSetting MINIPLAYER_DOUBLE_TAP_ACTION = new BooleanSetting("revanced_miniplayer_double_tap_action", TRUE, true, MINIPLAYER_ANY_MODERN);
|
public static final BooleanSetting MINIPLAYER_DOUBLE_TAP_ACTION = new BooleanSetting("revanced_miniplayer_double_tap_action", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||||
public static final BooleanSetting MINIPLAYER_DRAG_AND_DROP = new BooleanSetting("revanced_miniplayer_drag_and_drop", TRUE, true, MINIPLAYER_ANY_MODERN);
|
public static final BooleanSetting MINIPLAYER_DRAG_AND_DROP = new BooleanSetting("revanced_miniplayer_drag_and_drop", TRUE, true, MINIPLAYER_ANY_MODERN);
|
||||||
|
public static final BooleanSetting MINIPLAYER_HORIZONTAL_DRAG = new BooleanSetting("revanced_miniplayer_horizontal_drag", FALSE, true, new MiniplayerHorizontalDragAvailability());
|
||||||
public static final BooleanSetting MINIPLAYER_HIDE_EXPAND_CLOSE = new BooleanSetting("revanced_miniplayer_hide_expand_close", FALSE, true, new MiniplayerHideExpandCloseAvailability());
|
public static final BooleanSetting MINIPLAYER_HIDE_EXPAND_CLOSE = new BooleanSetting("revanced_miniplayer_hide_expand_close", FALSE, true, new MiniplayerHideExpandCloseAvailability());
|
||||||
public static final BooleanSetting MINIPLAYER_HIDE_SUBTEXT = new BooleanSetting("revanced_miniplayer_hide_subtext", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1, MODERN_3));
|
public static final BooleanSetting MINIPLAYER_HIDE_SUBTEXT = new BooleanSetting("revanced_miniplayer_hide_subtext", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1, MODERN_3));
|
||||||
public static final BooleanSetting MINIPLAYER_HIDE_REWIND_FORWARD = new BooleanSetting("revanced_miniplayer_hide_rewind_forward", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1));
|
public static final BooleanSetting MINIPLAYER_HIDE_REWIND_FORWARD = new BooleanSetting("revanced_miniplayer_hide_rewind_forward", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1));
|
||||||
|
@ -1133,17 +1133,6 @@ public final class app/revanced/patches/youtube/layout/hide/time/HideTimestampPa
|
|||||||
public static final fun getHideTimestampPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getHideTimestampPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/miniplayer/FingerprintsKt {
|
|
||||||
public static final field ANIMATION_INTERPOLATION_FEATURE_KEY J
|
|
||||||
public static final field DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL J
|
|
||||||
public static final field DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL J
|
|
||||||
public static final field DROP_SHADOW_FEATURE_KEY J
|
|
||||||
public static final field INITIAL_SIZE_FEATURE_KEY_LITERAL J
|
|
||||||
public static final field MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL J
|
|
||||||
public static final field MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY J
|
|
||||||
public static final field ROUNDED_CORNERS_FEATURE_KEY J
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatchKt {
|
public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatchKt {
|
||||||
public static final fun getFloatyBarButtonTopMargin ()J
|
public static final fun getFloatyBarButtonTopMargin ()J
|
||||||
public static final fun getMiniplayerMaxSize ()J
|
public static final fun getMiniplayerMaxSize ()J
|
||||||
@ -1188,10 +1177,6 @@ public final class app/revanced/patches/youtube/layout/searchbar/WideSearchbarPa
|
|||||||
public static final fun getWideSearchbarPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getWideSearchbarPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/seekbar/FingerprintsKt {
|
|
||||||
public static final field PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG J
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatchKt {
|
public final class app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatchKt {
|
||||||
public static final fun getSeekbarColorPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSeekbarColorPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@ -1274,10 +1259,6 @@ public final class app/revanced/patches/youtube/misc/extension/SharedExtensionPa
|
|||||||
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/fix/cairo/FingerprintsKt {
|
|
||||||
public static final field CAIRO_CONFIG_LITERAL_VALUE J
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatchKt {
|
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatchKt {
|
||||||
public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("SpellCheckingInspection")
|
||||||
|
|
||||||
package app.revanced.patches.youtube.layout.miniplayer
|
package app.revanced.patches.youtube.layout.miniplayer
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
@ -33,16 +35,14 @@ internal val miniplayerModernCloseButtonFingerprint = fingerprint {
|
|||||||
literal { modernMiniplayerClose }
|
literal { modernMiniplayerClose }
|
||||||
}
|
}
|
||||||
|
|
||||||
const val MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL = 45622882L
|
internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L
|
||||||
|
|
||||||
// In later targets this feature flag does nothing and is dead code.
|
// In later targets this feature flag does nothing and is dead code.
|
||||||
const val MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY = 45630429L
|
internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L
|
||||||
const val DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL = 45628823L
|
internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L
|
||||||
const val DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL = 45628752L
|
internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L
|
||||||
const val INITIAL_SIZE_FEATURE_KEY_LITERAL = 45640023L
|
internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L
|
||||||
const val ANIMATION_INTERPOLATION_FEATURE_KEY = 45647018L
|
internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
||||||
const val DROP_SHADOW_FEATURE_KEY = 45652223L
|
internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L
|
||||||
const val ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
|
||||||
|
|
||||||
internal val miniplayerModernConstructorFingerprint = fingerprint {
|
internal val miniplayerModernConstructorFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("SpellCheckingInspection")
|
||||||
|
|
||||||
package app.revanced.patches.youtube.layout.miniplayer
|
package app.revanced.patches.youtube.layout.miniplayer
|
||||||
|
|
||||||
import app.revanced.patcher.Match
|
import app.revanced.patcher.Match
|
||||||
@ -204,6 +206,10 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag")
|
||||||
|
}
|
||||||
|
|
||||||
if (is_19_36_or_greater) {
|
if (is_19_36_or_greater) {
|
||||||
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
||||||
}
|
}
|
||||||
@ -291,7 +297,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
addInstructions(
|
addInstructions(
|
||||||
targetIndex + 1,
|
targetIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(F)F
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(F)F
|
||||||
move-result v$register
|
move-result v$register
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
@ -302,13 +308,13 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
* Adds an override to specify which modern miniplayer is used.
|
* Adds an override to specify which modern miniplayer is used.
|
||||||
*/
|
*/
|
||||||
fun MutableMethod.insertModernMiniplayerTypeOverride(iPutIndex: Int) {
|
fun MutableMethod.insertModernMiniplayerTypeOverride(iPutIndex: Int) {
|
||||||
val targetInstruction = getInstruction<TwoRegisterInstruction>(iPutIndex)
|
val register = getInstruction<TwoRegisterInstruction>(iPutIndex).registerA
|
||||||
|
|
||||||
addInstructionsAtControlFlowLabel(
|
addInstructionsAtControlFlowLabel(
|
||||||
iPutIndex,
|
iPutIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static { v${targetInstruction.registerA} }, $EXTENSION_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I
|
||||||
move-result v${targetInstruction.registerA}
|
move-result v$register
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -378,24 +384,31 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
|
|
||||||
if (is_19_23_or_greater) {
|
if (is_19_23_or_greater) {
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL,
|
MINIPLAYER_DRAG_DROP_FEATURE_KEY,
|
||||||
"enableMiniplayerDragAndDrop",
|
"enableMiniplayerDragAndDrop",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_19_43_or_greater) {
|
||||||
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
|
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
|
||||||
|
"setHorizontalDrag",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY,
|
MINIPLAYER_MODERN_FEATURE_LEGACY_KEY,
|
||||||
"getModernMiniplayerOverride",
|
"getModernMiniplayerOverride",
|
||||||
)
|
)
|
||||||
|
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL,
|
MINIPLAYER_MODERN_FEATURE_KEY,
|
||||||
"getModernFeatureFlagsActiveOverride",
|
"getModernFeatureFlagsActiveOverride",
|
||||||
)
|
)
|
||||||
|
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL,
|
MINIPLAYER_DOUBLE_TAP_FEATURE_KEY,
|
||||||
"enableMiniplayerDoubleTapAction",
|
"enableMiniplayerDoubleTapAction",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -403,7 +416,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
if (is_19_26_or_greater) {
|
if (is_19_26_or_greater) {
|
||||||
miniplayerModernConstructorMatch.mutableMethod.apply {
|
miniplayerModernConstructorMatch.mutableMethod.apply {
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
|
||||||
INITIAL_SIZE_FEATURE_KEY_LITERAL,
|
MINIPLAYER_INITIAL_SIZE_FEATURE_KEY,
|
||||||
)
|
)
|
||||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT)
|
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT)
|
||||||
|
|
||||||
@ -418,7 +431,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override a mininimum miniplayer size constant.
|
// Override a minimum size constant.
|
||||||
miniplayerMinimumSizeMatch.mutableMethod.apply {
|
miniplayerMinimumSizeMatch.mutableMethod.apply {
|
||||||
val index = indexOfFirstInstructionOrThrow {
|
val index = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.CONST_16 && (this as NarrowLiteralInstruction).narrowLiteral == 192
|
opcode == Opcode.CONST_16 && (this as NarrowLiteralInstruction).narrowLiteral == 192
|
||||||
@ -432,22 +445,9 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_19_32_or_greater) {
|
|
||||||
// Feature is not exposed in the settings, and currently only for debugging.
|
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueFloatOverride(
|
|
||||||
ANIMATION_INTERPOLATION_FEATURE_KEY,
|
|
||||||
"setMovementBoundFactor",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_19_36_or_greater) {
|
if (is_19_36_or_greater) {
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||||
DROP_SHADOW_FEATURE_KEY,
|
MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY,
|
||||||
"setDropShadow",
|
|
||||||
)
|
|
||||||
|
|
||||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
|
||||||
ROUNDED_CORNERS_FEATURE_KEY,
|
|
||||||
"setRoundedCorners",
|
"setRoundedCorners",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -551,9 +551,9 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V
|
invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V
|
||||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V
|
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V
|
||||||
return-void
|
return-void
|
||||||
""",
|
"""
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
@ -34,7 +34,7 @@ internal val shortsSeekbarColorFingerprint = fingerprint {
|
|||||||
literal { reelTimeBarPlayedColorId }
|
literal { reelTimeBarPlayedColorId }
|
||||||
}
|
}
|
||||||
|
|
||||||
const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
internal const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
||||||
|
|
||||||
internal val playerSeekbarGradientConfigFingerprint = fingerprint {
|
internal val playerSeekbarGradientConfigFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
@ -57,22 +57,62 @@ val enableDebuggingPatch = bytecodePatch(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hook the method that looks up if a feature flag is active or not.
|
// Hook the methods that look up if a feature flag is active.
|
||||||
experimentalFeatureFlagFingerprint.applyMatch(
|
|
||||||
|
experimentalBooleanFeatureFlagFingerprint.applyMatch(
|
||||||
context,
|
context,
|
||||||
experimentalFeatureFlagParentMatch
|
experimentalFeatureFlagParentMatch
|
||||||
).mutableMethod.apply {
|
).mutableMethod.apply {
|
||||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
|
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
|
||||||
|
|
||||||
|
// It appears that all usage of this method has a default of 'false',
|
||||||
|
// so there's no need to pass in the default.
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"""
|
"""
|
||||||
move-result v0
|
move-result v0
|
||||||
invoke-static { p1, p2, v0 }, $EXTENSION_CLASS_DESCRIPTOR->isFeatureFlagEnabled(JZ)Z
|
invoke-static { v0, p1, p2 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZJ)Z
|
||||||
move-result v0
|
move-result v0
|
||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
experimentalDoubleFeatureFlagFingerprint.applyMatch(
|
||||||
|
context,
|
||||||
|
experimentalFeatureFlagParentMatch
|
||||||
|
).mutableMethod.apply {
|
||||||
|
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
|
||||||
|
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
|
||||||
|
move-result-wide v0
|
||||||
|
return-wide v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
experimentalLongFeatureFlagFingerprint.applyMatch(
|
||||||
|
context,
|
||||||
|
experimentalFeatureFlagParentMatch
|
||||||
|
).mutableMethod.apply {
|
||||||
|
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
move-result-wide v0
|
||||||
|
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
|
||||||
|
move-result-wide v0
|
||||||
|
return-wide v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// There exists other experimental accessor methods for String, byte[], and wrappers for obfuscated classes,
|
||||||
|
// but currently none of those are hooked.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,21 @@ internal val experimentalFeatureFlagParentFingerprint = fingerprint {
|
|||||||
strings("Unable to parse proto typed experiment flag: ")
|
strings("Unable to parse proto typed experiment flag: ")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val experimentalFeatureFlagFingerprint = fingerprint {
|
internal val experimentalBooleanFeatureFlagFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returns("Z")
|
returns("Z")
|
||||||
parameters("J", "Z")
|
parameters("J", "Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val experimentalDoubleFeatureFlagFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("D")
|
||||||
|
parameters("J", "D")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val experimentalLongFeatureFlagFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("J")
|
||||||
|
parameters("J", "J")
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
* When this value is true, Cairo Fragment is used.
|
* When this value is true, Cairo Fragment is used.
|
||||||
* In this case, some of the patches may be broken, so set this value to FALSE.
|
* In this case, some of the patches may be broken, so set this value to FALSE.
|
||||||
*/
|
*/
|
||||||
const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
||||||
|
|
||||||
internal val cairoFragmentConfigFingerprint = fingerprint {
|
internal val cairoFragmentConfigFingerprint = fingerprint {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
@ -1035,6 +1035,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
|||||||
<string name="revanced_miniplayer_drag_and_drop_title">Enable drag and drop</string>
|
<string name="revanced_miniplayer_drag_and_drop_title">Enable drag and drop</string>
|
||||||
<string name="revanced_miniplayer_drag_and_drop_summary_on">Drag and drop is enabled\n\nMiniplayer can be dragged to any corner of the screen</string>
|
<string name="revanced_miniplayer_drag_and_drop_summary_on">Drag and drop is enabled\n\nMiniplayer can be dragged to any corner of the screen</string>
|
||||||
<string name="revanced_miniplayer_drag_and_drop_summary_off">Drag and drop is disabled</string>
|
<string name="revanced_miniplayer_drag_and_drop_summary_off">Drag and drop is disabled</string>
|
||||||
|
<string name="revanced_miniplayer_horizontal_drag_title">Enable horizontal drag gesture</string>
|
||||||
|
<string name="revanced_miniplayer_horizontal_drag_summary_on">Horizontal drag gesture enabled\n\nMiniplayer can be dragged off screen to the left or right</string>
|
||||||
|
<string name="revanced_miniplayer_horizontal_drag_summary_off">Horizontal drag gesture disabled</string>
|
||||||
<string name="revanced_miniplayer_hide_expand_close_title">Hide close button</string>
|
<string name="revanced_miniplayer_hide_expand_close_title">Hide close button</string>
|
||||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Close button is hidden</string>
|
<string name="revanced_miniplayer_hide_expand_close_summary_on">Close button is hidden</string>
|
||||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Close button is shown</string>
|
<string name="revanced_miniplayer_hide_expand_close_summary_off">Close button is shown</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user