mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-29 13:20:19 +02:00
feat(YouTube): Support version 19.44.39
This commit is contained in:
parent
2b77e46f5e
commit
dc0a5973ad
@ -18,6 +18,7 @@ public class SponsorBlockSettings {
|
|||||||
public void settingsImported(@Nullable Context context) {
|
public void settingsImported(@Nullable Context context) {
|
||||||
SegmentCategory.loadAllCategoriesFromSettings();
|
SegmentCategory.loadAllCategoriesFromSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void settingsExported(@Nullable Context context) {
|
public void settingsExported(@Nullable Context context) {
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package app.revanced.extension.music.utils;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
@ -64,14 +64,14 @@ public class GmsCoreSupport {
|
|||||||
// Use a delay to allow the activity to finish initializing.
|
// Use a delay to allow the activity to finish initializing.
|
||||||
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
|
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
|
||||||
Utils.runOnMainThreadDelayed(() ->
|
Utils.runOnMainThreadDelayed(() ->
|
||||||
// Do not set cancelable to false, to allow using back button to skip the action,
|
// Do not set cancelable to false, to allow using back button to skip the action,
|
||||||
// just in case the battery change can never be satisfied.
|
// just in case the battery change can never be satisfied.
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context)
|
||||||
.setIconAttribute(android.R.attr.alertDialogIcon)
|
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||||
.setTitle(str("gms_core_dialog_title"))
|
.setTitle(str("gms_core_dialog_title"))
|
||||||
.setMessage(str(dialogMessageRef))
|
.setMessage(str(dialogMessageRef))
|
||||||
.setPositiveButton(str(positiveButtonTextRef), onPositiveClickListener)
|
.setPositiveButton(str(positiveButtonTextRef), onPositiveClickListener)
|
||||||
.show(),
|
.show(),
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,11 @@ public class PlayerPatch {
|
|||||||
|
|
||||||
// region [Ambient mode control] patch
|
// region [Ambient mode control] patch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant found in: androidx.window.embedding.DividerAttributes
|
||||||
|
*/
|
||||||
|
private static final int DIVIDER_ATTRIBUTES_COLOR_SYSTEM_DEFAULT = -16777216;
|
||||||
|
|
||||||
public static boolean bypassAmbientModeRestrictions(boolean original) {
|
public static boolean bypassAmbientModeRestrictions(boolean original) {
|
||||||
return (!Settings.BYPASS_AMBIENT_MODE_RESTRICTIONS.get() && original) || Settings.DISABLE_AMBIENT_MODE.get();
|
return (!Settings.BYPASS_AMBIENT_MODE_RESTRICTIONS.get() && original) || Settings.DISABLE_AMBIENT_MODE.get();
|
||||||
}
|
}
|
||||||
@ -82,6 +87,14 @@ public class PlayerPatch {
|
|||||||
return !Settings.DISABLE_AMBIENT_MODE_IN_FULLSCREEN.get();
|
return !Settings.DISABLE_AMBIENT_MODE_IN_FULLSCREEN.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getFullScreenBackgroundColor(int originalColor) {
|
||||||
|
if (Settings.DISABLE_AMBIENT_MODE_IN_FULLSCREEN.get()) {
|
||||||
|
return DIVIDER_ATTRIBUTES_COLOR_SYSTEM_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalColor;
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region [Change player flyout menu toggles] patch
|
// region [Change player flyout menu toggles] patch
|
||||||
@ -424,6 +437,35 @@ public class PlayerPatch {
|
|||||||
return !Settings.HIDE_PLAYER_PREVIOUS_NEXT_BUTTON.get() && previousOrNextButtonVisible;
|
return !Settings.HIDE_PLAYER_PREVIOUS_NEXT_BUTTON.get() && previousOrNextButtonVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int playerControlPreviousButtonTouchAreaId =
|
||||||
|
ResourceUtils.getIdIdentifier("player_control_previous_button_touch_area");
|
||||||
|
private static final int playerControlNextButtonTouchAreaId =
|
||||||
|
ResourceUtils.getIdIdentifier("player_control_next_button_touch_area");
|
||||||
|
|
||||||
|
public static void hidePreviousNextButtons(View parentView) {
|
||||||
|
if (!Settings.HIDE_PLAYER_PREVIOUS_NEXT_BUTTON.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must use a deferred call to main thread to hide the button.
|
||||||
|
// Otherwise the layout crashes if set to hidden now.
|
||||||
|
Utils.runOnMainThread(() -> {
|
||||||
|
hideView(parentView, playerControlPreviousButtonTouchAreaId);
|
||||||
|
hideView(parentView, playerControlNextButtonTouchAreaId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void hideView(View parentView, int resourceId) {
|
||||||
|
View nextPreviousButton = parentView.findViewById(resourceId);
|
||||||
|
|
||||||
|
if (nextPreviousButton == null) {
|
||||||
|
Logger.printException(() -> "Could not find player previous / next button");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.hideViewByRemovingFromParentUnderCondition(true, nextPreviousButton);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean hideMusicButton() {
|
public static boolean hideMusicButton() {
|
||||||
return Settings.HIDE_PLAYER_YOUTUBE_MUSIC_BUTTON.get();
|
return Settings.HIDE_PLAYER_YOUTUBE_MUSIC_BUTTON.get();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package app.revanced.extension.youtube.patches.shorts;
|
package app.revanced.extension.youtube.patches.shorts;
|
||||||
|
|
||||||
|
import static app.revanced.extension.shared.utils.ResourceUtils.getString;
|
||||||
|
import static app.revanced.extension.shared.utils.Utils.dpToPx;
|
||||||
|
import static app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter.isShortsFlyoutMenuVisible;
|
||||||
|
import static app.revanced.extension.youtube.utils.ExtendedUtils.isSpoofingToLessThan;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
@ -10,13 +15,26 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.graphics.drawable.StateListDrawable;
|
import android.graphics.drawable.StateListDrawable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.*;
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
import app.revanced.extension.shared.utils.Logger;
|
import app.revanced.extension.shared.utils.Logger;
|
||||||
import app.revanced.extension.shared.utils.ResourceUtils;
|
import app.revanced.extension.shared.utils.ResourceUtils;
|
||||||
@ -26,17 +44,6 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
import app.revanced.extension.youtube.utils.ThemeUtils;
|
import app.revanced.extension.youtube.utils.ThemeUtils;
|
||||||
import app.revanced.extension.youtube.utils.VideoUtils;
|
import app.revanced.extension.youtube.utils.VideoUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static app.revanced.extension.shared.utils.ResourceUtils.getString;
|
|
||||||
import static app.revanced.extension.shared.utils.Utils.dpToPx;
|
|
||||||
import static app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter.isShortsFlyoutMenuVisible;
|
|
||||||
import static app.revanced.extension.youtube.utils.ExtendedUtils.isSpoofingToLessThan;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class CustomActionsPatch {
|
public final class CustomActionsPatch {
|
||||||
|
@ -34,6 +34,7 @@ public class SponsorBlockSettings {
|
|||||||
SegmentCategory.loadAllCategoriesFromSettings();
|
SegmentCategory.loadAllCategoriesFromSettings();
|
||||||
SponsorBlockSettingsPreference.updateSegmentCategories();
|
SponsorBlockSettingsPreference.updateSegmentCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void settingsExported(@Nullable Context context) {
|
public void settingsExported(@Nullable Context context) {
|
||||||
showExportWarningIfNeeded(context);
|
showExportWarningIfNeeded(context);
|
||||||
|
@ -22,11 +22,11 @@ internal val actionBarRingoBackgroundFingerprint = legacyFingerprint(
|
|||||||
returnType = "Landroid/view/View;",
|
returnType = "Landroid/view/View;",
|
||||||
literals = listOf(actionBarRingoBackground),
|
literals = listOf(actionBarRingoBackground),
|
||||||
customFingerprint = { method, _ ->
|
customFingerprint = { method, _ ->
|
||||||
indexOfStaticInstruction(method) >= 0
|
indexOfActionBarRingoBackgroundTabletInstruction(method) >= 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun indexOfStaticInstruction(method: Method) =
|
internal fun indexOfActionBarRingoBackgroundTabletInstruction(method: Method) =
|
||||||
method.indexOfFirstInstruction {
|
method.indexOfFirstInstruction {
|
||||||
val reference = getReference<MethodReference>()
|
val reference = getReference<MethodReference>()
|
||||||
opcode == Opcode.INVOKE_STATIC &&
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
@ -54,7 +54,7 @@ internal val actionBarRingoTextFingerprint = legacyFingerprint(
|
|||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
customFingerprint = { method, _ ->
|
customFingerprint = { method, _ ->
|
||||||
indexOfStartDelayInstruction(method) >= 0 &&
|
indexOfStartDelayInstruction(method) >= 0 &&
|
||||||
indexOfStaticInstructions(method) >= 0
|
indexOfActionBarRingoTextTabletInstructions(method) >= 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ internal fun indexOfStartDelayInstruction(method: Method) =
|
|||||||
getReference<MethodReference>()?.name == "setStartDelay"
|
getReference<MethodReference>()?.name == "setStartDelay"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun indexOfStaticInstructions(method: Method) =
|
internal fun indexOfActionBarRingoTextTabletInstructions(method: Method) =
|
||||||
method.indexOfFirstInstructionReversed(indexOfStartDelayInstruction(method)) {
|
method.indexOfFirstInstructionReversed(indexOfStartDelayInstruction(method)) {
|
||||||
val reference = getReference<MethodReference>()
|
val reference = getReference<MethodReference>()
|
||||||
opcode == Opcode.INVOKE_STATIC &&
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
@ -175,24 +175,6 @@ internal val setActionBarRingoFingerprint = legacyFingerprint(
|
|||||||
literals = listOf(actionBarRingo),
|
literals = listOf(actionBarRingo),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val setWordMarkHeaderFingerprint = legacyFingerprint(
|
|
||||||
name = "setWordMarkHeaderFingerprint",
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("Landroid/widget/ImageView;"),
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
Opcode.IF_NEZ,
|
|
||||||
Opcode.IGET_BOOLEAN,
|
|
||||||
Opcode.IF_EQZ,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.CONST,
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
internal val yoodlesImageViewFingerprint = legacyFingerprint(
|
internal val yoodlesImageViewFingerprint = legacyFingerprint(
|
||||||
name = "yoodlesImageViewFingerprint",
|
name = "yoodlesImageViewFingerprint",
|
||||||
|
@ -169,7 +169,7 @@ val toolBarComponentsPatch = bytecodePatch(
|
|||||||
"invoke-static {v$viewRegister}, $GENERAL_CLASS_DESCRIPTOR->setWideSearchBarLayout(Landroid/view/View;)V"
|
"invoke-static {v$viewRegister}, $GENERAL_CLASS_DESCRIPTOR->setWideSearchBarLayout(Landroid/view/View;)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
val targetIndex = indexOfStaticInstruction(this) + 1
|
val targetIndex = indexOfActionBarRingoBackgroundTabletInstruction(this) + 1
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
injectSearchBarHook(
|
injectSearchBarHook(
|
||||||
@ -180,7 +180,7 @@ val toolBarComponentsPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
actionBarRingoTextFingerprint.methodOrThrow(actionBarRingoBackgroundFingerprint).apply {
|
actionBarRingoTextFingerprint.methodOrThrow(actionBarRingoBackgroundFingerprint).apply {
|
||||||
val targetIndex = indexOfStaticInstruction(this) + 1
|
val targetIndex = indexOfActionBarRingoTextTabletInstructions(this) + 1
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
injectSearchBarHook(
|
injectSearchBarHook(
|
||||||
|
@ -6,15 +6,20 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR
|
import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.youtube.utils.patch.PatchList.AMBIENT_MODE_CONTROL
|
import app.revanced.patches.youtube.utils.patch.PatchList.AMBIENT_MODE_CONTROL
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.is_19_41_or_greater
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
||||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||||
import app.revanced.util.findMethodOrThrow
|
import app.revanced.util.findMethodOrThrow
|
||||||
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||||
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.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
@ -26,7 +31,10 @@ val ambientModeSwitchPatch = bytecodePatch(
|
|||||||
) {
|
) {
|
||||||
compatibleWith(COMPATIBLE_PACKAGE)
|
compatibleWith(COMPATIBLE_PACKAGE)
|
||||||
|
|
||||||
dependsOn(settingsPatch)
|
dependsOn(
|
||||||
|
settingsPatch,
|
||||||
|
versionCheckPatch,
|
||||||
|
)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
// region patch for bypass ambient mode restrictions
|
// region patch for bypass ambient mode restrictions
|
||||||
@ -83,10 +91,29 @@ val ambientModeSwitchPatch = bytecodePatch(
|
|||||||
|
|
||||||
// region patch for disable ambient mode in fullscreen
|
// region patch for disable ambient mode in fullscreen
|
||||||
|
|
||||||
ambientModeInFullscreenFingerprint.injectLiteralInstructionBooleanCall(
|
if (!is_19_41_or_greater) {
|
||||||
45389368L,
|
ambientModeInFullscreenFingerprint.injectLiteralInstructionBooleanCall(
|
||||||
"$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z"
|
AMBIENT_MODE_IN_FULLSCREEN_FEATURE_FLAG,
|
||||||
)
|
"$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_19_34_or_greater) {
|
||||||
|
setFullScreenBackgroundColorFingerprint.methodOrThrow().apply {
|
||||||
|
val insertIndex = indexOfFirstInstructionReversedOrThrow {
|
||||||
|
getReference<MethodReference>()?.name == "setBackgroundColor"
|
||||||
|
}
|
||||||
|
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $PLAYER_CLASS_DESCRIPTOR->getFullScreenBackgroundColor(I)I
|
||||||
|
move-result v$register
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -4,10 +4,12 @@ import app.revanced.util.fingerprint.legacyFingerprint
|
|||||||
import app.revanced.util.or
|
import app.revanced.util.or
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal const val AMBIENT_MODE_IN_FULLSCREEN_FEATURE_FLAG = 45389368L
|
||||||
|
|
||||||
internal val ambientModeInFullscreenFingerprint = legacyFingerprint(
|
internal val ambientModeInFullscreenFingerprint = legacyFingerprint(
|
||||||
name = "ambientModeInFullscreenFingerprint",
|
name = "ambientModeInFullscreenFingerprint",
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
literals = listOf(45389368L),
|
literals = listOf(AMBIENT_MODE_IN_FULLSCREEN_FEATURE_FLAG),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val powerSaveModeBroadcastReceiverFingerprint = legacyFingerprint(
|
internal val powerSaveModeBroadcastReceiverFingerprint = legacyFingerprint(
|
||||||
@ -30,4 +32,15 @@ internal val powerSaveModeSyntheticFingerprint = legacyFingerprint(
|
|||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("Ljava/lang/Object;"),
|
parameters = listOf("Ljava/lang/Object;"),
|
||||||
strings = listOf("android.os.action.POWER_SAVE_MODE_CHANGED")
|
strings = listOf("android.os.action.POWER_SAVE_MODE_CHANGED")
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val setFullScreenBackgroundColorFingerprint = legacyFingerprint(
|
||||||
|
name = "setFullScreenBackgroundColorFingerprint",
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||||
|
parameters = listOf("Z", "I", "I", "I", "I"),
|
||||||
|
customFingerprint = { method, classDef ->
|
||||||
|
classDef.type.endsWith("/YouTubePlayerViewNotForReflection;")
|
||||||
|
&& method.name == "onLayout"
|
||||||
|
},
|
||||||
)
|
)
|
@ -14,22 +14,27 @@ import app.revanced.patches.youtube.utils.fix.bottomui.cfBottomUIPatch
|
|||||||
import app.revanced.patches.youtube.utils.layoutConstructorFingerprint
|
import app.revanced.patches.youtube.utils.layoutConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_PLAYER_BUTTONS
|
import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_PLAYER_BUTTONS
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_18_31_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_18_31_or_greater
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.resourceid.autoNavToggle
|
import app.revanced.patches.youtube.utils.resourceid.autoNavToggle
|
||||||
import app.revanced.patches.youtube.utils.resourceid.fullScreenButton
|
import app.revanced.patches.youtube.utils.resourceid.fullScreenButton
|
||||||
import app.revanced.patches.youtube.utils.resourceid.playerCollapseButton
|
import app.revanced.patches.youtube.utils.resourceid.playerCollapseButton
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.playerControlPreviousButtonTouchArea
|
||||||
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
||||||
import app.revanced.patches.youtube.utils.resourceid.titleAnchor
|
import app.revanced.patches.youtube.utils.resourceid.titleAnchor
|
||||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
||||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||||
import app.revanced.util.fingerprint.matchOrThrow
|
import app.revanced.util.fingerprint.matchOrThrow
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
|
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 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.RegisterRangeInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
private const val HAS_NEXT = 5
|
private const val HAS_NEXT = 5
|
||||||
private const val HAS_PREVIOUS = 6
|
private const val HAS_PREVIOUS = 6
|
||||||
@ -162,21 +167,40 @@ val playerButtonsPatch = bytecodePatch(
|
|||||||
|
|
||||||
// region patch for hide previous and next button
|
// region patch for hide previous and next button
|
||||||
|
|
||||||
playerControlsVisibilityModelFingerprint.methodOrThrow().apply {
|
if (is_19_34_or_greater) {
|
||||||
val callIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT_RANGE)
|
layoutConstructorFingerprint.methodOrThrow().apply {
|
||||||
val callInstruction = getInstruction<RegisterRangeInstruction>(callIndex)
|
val resourceIndex = indexOfFirstLiteralInstructionOrThrow(playerControlPreviousButtonTouchArea)
|
||||||
|
|
||||||
val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT
|
val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
|
||||||
val hasPreviousParameterRegister = callInstruction.startRegister + HAS_PREVIOUS
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
|
getReference<MethodReference>()?.parameterTypes?.firstOrNull() == "Landroid/view/View;"
|
||||||
|
}
|
||||||
|
|
||||||
addInstructions(
|
val viewRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
callIndex, """
|
|
||||||
invoke-static { v$hasNextParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z
|
addInstruction(
|
||||||
move-result v$hasNextParameterRegister
|
insertIndex,
|
||||||
invoke-static { v$hasPreviousParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z
|
"invoke-static { v$viewRegister }, $PLAYER_CLASS_DESCRIPTOR" +
|
||||||
move-result v$hasPreviousParameterRegister
|
"->hidePreviousNextButtons(Landroid/view/View;)V",
|
||||||
"""
|
)
|
||||||
)
|
}
|
||||||
|
} else {
|
||||||
|
playerControlsVisibilityModelFingerprint.methodOrThrow().apply {
|
||||||
|
val callIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT_RANGE)
|
||||||
|
val callInstruction = getInstruction<RegisterRangeInstruction>(callIndex)
|
||||||
|
|
||||||
|
val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT
|
||||||
|
val hasPreviousParameterRegister = callInstruction.startRegister + HAS_PREVIOUS
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
callIndex, """
|
||||||
|
invoke-static { v$hasNextParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z
|
||||||
|
move-result v$hasNextParameterRegister
|
||||||
|
invoke-static { v$hasPreviousParameterRegister }, $PLAYER_CLASS_DESCRIPTOR->hidePreviousNextButton(Z)Z
|
||||||
|
move-result v$hasPreviousParameterRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
@ -9,7 +9,6 @@ import app.revanced.patches.youtube.utils.resourceid.easySeekEduContainer
|
|||||||
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutCircle
|
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutCircle
|
||||||
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutIcon
|
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutIcon
|
||||||
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutVideo
|
import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutVideo
|
||||||
import app.revanced.patches.youtube.utils.resourceid.notice
|
|
||||||
import app.revanced.patches.youtube.utils.resourceid.offlineActionsVideoDeletedUndoSnackbarText
|
import app.revanced.patches.youtube.utils.resourceid.offlineActionsVideoDeletedUndoSnackbarText
|
||||||
import app.revanced.patches.youtube.utils.resourceid.scrubbing
|
import app.revanced.patches.youtube.utils.resourceid.scrubbing
|
||||||
import app.revanced.patches.youtube.utils.resourceid.seekEasyHorizontalTouchOffsetToStartScrubbing
|
import app.revanced.patches.youtube.utils.resourceid.seekEasyHorizontalTouchOffsetToStartScrubbing
|
||||||
@ -207,11 +206,12 @@ internal val lithoComponentOnClickListenerFingerprint = legacyFingerprint(
|
|||||||
literals = listOf(componentLongClickListener),
|
literals = listOf(componentLongClickListener),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val noticeOnClickListenerFingerprint = legacyFingerprint(
|
internal val engagementPanelPlaylistSyntheticFingerprint = legacyFingerprint(
|
||||||
name = "noticeOnClickListenerFingerprint",
|
name = "engagementPanelPlaylistSyntheticFingerprint",
|
||||||
returnType = "V",
|
strings = listOf("engagement-panel-playlist"),
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
customFingerprint = { _, classDef ->
|
||||||
literals = listOf(notice),
|
classDef.interfaces.contains("Landroid/view/View${'$'}OnClickListener;")
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val offlineActionsOnClickListenerFingerprint = legacyFingerprint(
|
internal val offlineActionsOnClickListenerFingerprint = legacyFingerprint(
|
||||||
|
@ -369,30 +369,32 @@ val playerComponentsPatch = bytecodePatch(
|
|||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
lithoComponentOnClickListenerFingerprint,
|
lithoComponentOnClickListenerFingerprint,
|
||||||
noticeOnClickListenerFingerprint,
|
|
||||||
offlineActionsOnClickListenerFingerprint,
|
offlineActionsOnClickListenerFingerprint,
|
||||||
startVideoInformerFingerprint,
|
|
||||||
).forEach { fingerprint ->
|
).forEach { fingerprint ->
|
||||||
fingerprint.methodOrThrow().apply {
|
fingerprint.methodOrThrow().apply {
|
||||||
if (fingerprint == startVideoInformerFingerprint) {
|
val syntheticIndex =
|
||||||
hookInitVideoPanel(1)
|
indexOfFirstInstruction(Opcode.NEW_INSTANCE)
|
||||||
} else {
|
if (syntheticIndex >= 0) {
|
||||||
val syntheticIndex =
|
val syntheticReference =
|
||||||
indexOfFirstInstruction(Opcode.NEW_INSTANCE)
|
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
||||||
if (syntheticIndex >= 0) {
|
|
||||||
val syntheticReference =
|
|
||||||
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
|
||||||
|
|
||||||
findMethodOrThrow(syntheticReference) {
|
findMethodOrThrow(syntheticReference) {
|
||||||
name == "onClick"
|
name == "onClick"
|
||||||
}.hookInitVideoPanel(0)
|
}.hookInitVideoPanel(0)
|
||||||
} else {
|
} else {
|
||||||
println("WARNING: target Opcode not found in ${fingerprint.first}")
|
println("WARNING: target Opcode not found in ${fingerprint.first}")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findMethodOrThrow(
|
||||||
|
engagementPanelPlaylistSyntheticFingerprint.methodOrThrow().definingClass
|
||||||
|
) {
|
||||||
|
name == "onClick"
|
||||||
|
}.hookInitVideoPanel(0)
|
||||||
|
|
||||||
|
startVideoInformerFingerprint.methodOrThrow().hookInitVideoPanel(1)
|
||||||
|
|
||||||
engagementPanelBuilderFingerprint.methodOrThrow().apply {
|
engagementPanelBuilderFingerprint.methodOrThrow().apply {
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
0, """
|
0, """
|
||||||
|
@ -16,8 +16,8 @@ import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
|||||||
import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_19_02_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_19_02_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewHook
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverPatch
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewPatch
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverHook
|
||||||
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
||||||
import app.revanced.patches.youtube.utils.rollingNumberTextViewAnimationUpdateFingerprint
|
import app.revanced.patches.youtube.utils.rollingNumberTextViewAnimationUpdateFingerprint
|
||||||
import app.revanced.patches.youtube.utils.rollingNumberTextViewFingerprint
|
import app.revanced.patches.youtube.utils.rollingNumberTextViewFingerprint
|
||||||
@ -43,9 +43,9 @@ val descriptionComponentsPatch = bytecodePatch(
|
|||||||
|
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
bottomSheetRecyclerViewPatch,
|
|
||||||
lithoFilterPatch,
|
lithoFilterPatch,
|
||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
|
recyclerViewTreeObserverPatch,
|
||||||
sharedResourceIdPatch,
|
sharedResourceIdPatch,
|
||||||
versionCheckPatch,
|
versionCheckPatch,
|
||||||
)
|
)
|
||||||
@ -117,7 +117,7 @@ val descriptionComponentsPatch = bytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
bottomSheetRecyclerViewHook("$PLAYER_CLASS_DESCRIPTOR->onVideoDescriptionCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
recyclerViewTreeObserverHook("$PLAYER_CLASS_DESCRIPTOR->onVideoDescriptionCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
||||||
|
|
||||||
settingArray += "SETTINGS: DESCRIPTION_INTERACTION"
|
settingArray += "SETTINGS: DESCRIPTION_INTERACTION"
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import app.revanced.patches.youtube.utils.layoutConstructorFingerprint
|
|||||||
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
|
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
|
||||||
import app.revanced.patches.youtube.utils.patch.PatchList.FULLSCREEN_COMPONENTS
|
import app.revanced.patches.youtube.utils.patch.PatchList.FULLSCREEN_COMPONENTS
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_18_42_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_18_42_or_greater
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.is_19_41_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.resourceid.autoNavPreviewStub
|
import app.revanced.patches.youtube.utils.resourceid.autoNavPreviewStub
|
||||||
import app.revanced.patches.youtube.utils.resourceid.fullScreenEngagementPanel
|
import app.revanced.patches.youtube.utils.resourceid.fullScreenEngagementPanel
|
||||||
@ -293,7 +294,7 @@ val fullscreenComponentsPatch = bytecodePatch(
|
|||||||
|
|
||||||
// region patch for keep landscape mode
|
// region patch for keep landscape mode
|
||||||
|
|
||||||
if (is_18_42_or_greater) {
|
if (is_18_42_or_greater && !is_19_41_or_greater) {
|
||||||
landScapeModeConfigFingerprint.methodOrThrow().apply {
|
landScapeModeConfigFingerprint.methodOrThrow().apply {
|
||||||
val insertIndex = implementation!!.instructions.lastIndex
|
val insertIndex = implementation!!.instructions.lastIndex
|
||||||
val insertRegister =
|
val insertRegister =
|
||||||
@ -319,6 +320,8 @@ val fullscreenComponentsPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
settingArray += "SETTINGS: KEEP_LANDSCAPE_MODE"
|
settingArray += "SETTINGS: KEEP_LANDSCAPE_MODE"
|
||||||
|
} else {
|
||||||
|
println("WARNING: \"Keep landscape mode\" is not supported in this version. Use YouTube 19.16.39 or earlier.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
@ -201,64 +201,59 @@ val overlayButtonsPatch = resourcePatch(
|
|||||||
"android.support.constraint.ConstraintLayout"
|
"android.support.constraint.ConstraintLayout"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Modify the layout of fullscreen button for newer YouTube versions (19.09.xx+)
|
// Note: Do not modify fullscreen button and multiview button
|
||||||
arrayOf(
|
document("res/layout/youtube_controls_bottom_ui_container.xml").use { document ->
|
||||||
"youtube_controls_bottom_ui_container.xml",
|
document.doRecursively loop@{ node ->
|
||||||
"youtube_controls_fullscreen_button.xml",
|
if (node !is Element) return@loop
|
||||||
"youtube_controls_cf_fullscreen_button.xml",
|
|
||||||
).forEach { xmlFile ->
|
|
||||||
val targetXml = get("res").resolve("layout").resolve(xmlFile)
|
|
||||||
if (targetXml.exists()) {
|
|
||||||
document("res/layout/$xmlFile").use { document ->
|
|
||||||
document.doRecursively loop@{ node ->
|
|
||||||
if (node !is Element) return@loop
|
|
||||||
|
|
||||||
// Change the relationship between buttons
|
// Change the relationship between buttons
|
||||||
node.getAttributeNode("yt:layout_constraintRight_toLeftOf")
|
node.getAttributeNode("yt:layout_constraintRight_toLeftOf")
|
||||||
?.let { attribute ->
|
?.let { attribute ->
|
||||||
if (attribute.textContent == "@id/fullscreen_button") {
|
if (attribute.textContent == "@id/fullscreen_button") {
|
||||||
attribute.textContent = "@+id/speed_dialog_button"
|
attribute.textContent = "@+id/speed_dialog_button"
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val (id, height, width) = Triple(
|
|
||||||
node.getAttribute("android:id"),
|
|
||||||
node.getAttribute("android:layout_height"),
|
|
||||||
node.getAttribute("android:layout_width")
|
|
||||||
)
|
|
||||||
val (heightIsNotZero, widthIsNotZero, isButton) = Triple(
|
|
||||||
height != "0.0dip",
|
|
||||||
width != "0.0dip",
|
|
||||||
id.endsWith("_button") || id == "@id/youtube_controls_fullscreen_button_stub"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Adjust TimeBar and Chapter bottom padding
|
|
||||||
val timBarItem = mutableMapOf(
|
|
||||||
"@id/time_bar_chapter_title" to "16.0dip",
|
|
||||||
"@id/timestamps_container" to "14.0dip"
|
|
||||||
)
|
|
||||||
|
|
||||||
val layoutHeightWidth = if (widerButtonsSpace == true)
|
|
||||||
"56.0dip"
|
|
||||||
else
|
|
||||||
"48.0dip"
|
|
||||||
|
|
||||||
if (isButton) {
|
|
||||||
node.setAttribute("android:layout_marginBottom", marginBottom)
|
|
||||||
node.setAttribute("android:paddingLeft", "0.0dip")
|
|
||||||
node.setAttribute("android:paddingRight", "0.0dip")
|
|
||||||
node.setAttribute("android:paddingBottom", "22.0dip")
|
|
||||||
if (heightIsNotZero && widthIsNotZero) {
|
|
||||||
node.setAttribute("android:layout_height", layoutHeightWidth)
|
|
||||||
node.setAttribute("android:layout_width", layoutHeightWidth)
|
|
||||||
}
|
|
||||||
} else if (timBarItem.containsKey(id)) {
|
|
||||||
node.setAttribute("android:layout_marginBottom", marginBottom)
|
|
||||||
if (widerButtonsSpace != true) {
|
|
||||||
node.setAttribute("android:paddingBottom", timBarItem.getValue(id))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val (id, height, width) = Triple(
|
||||||
|
node.getAttribute("android:id"),
|
||||||
|
node.getAttribute("android:layout_height"),
|
||||||
|
node.getAttribute("android:layout_width")
|
||||||
|
)
|
||||||
|
val (heightIsNotZero, widthIsNotZero, isButton) = Triple(
|
||||||
|
height != "0.0dip",
|
||||||
|
width != "0.0dip",
|
||||||
|
id.endsWith("_button") && id != "@id/multiview_button"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Adjust TimeBar and Chapter bottom padding
|
||||||
|
val timBarItem = mutableMapOf(
|
||||||
|
"@id/time_bar_chapter_title" to "16.0dip",
|
||||||
|
"@id/timestamps_container" to "14.0dip"
|
||||||
|
)
|
||||||
|
|
||||||
|
val layoutHeightWidth = if (widerButtonsSpace == true)
|
||||||
|
"56.0dip"
|
||||||
|
else
|
||||||
|
"48.0dip"
|
||||||
|
|
||||||
|
if (isButton) {
|
||||||
|
node.setAttribute("android:layout_marginBottom", marginBottom)
|
||||||
|
node.setAttribute("android:paddingLeft", "0.0dip")
|
||||||
|
node.setAttribute("android:paddingRight", "0.0dip")
|
||||||
|
node.setAttribute("android:paddingBottom", "22.0dip")
|
||||||
|
if (heightIsNotZero && widthIsNotZero) {
|
||||||
|
node.setAttribute("android:layout_height", layoutHeightWidth)
|
||||||
|
node.setAttribute("android:layout_width", layoutHeightWidth)
|
||||||
|
}
|
||||||
|
} else if (timBarItem.containsKey(id)) {
|
||||||
|
node.setAttribute("android:layout_marginBottom", marginBottom)
|
||||||
|
if (widerButtonsSpace != true) {
|
||||||
|
node.setAttribute("android:paddingBottom", timBarItem.getValue(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.equals("@id/youtube_controls_fullscreen_button_stub")) {
|
||||||
|
node.setAttribute("android:layout_width", layoutHeightWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater
|
|||||||
import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewHook
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverPatch
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewPatch
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverHook
|
||||||
import app.revanced.patches.youtube.utils.resourceid.bottomBarContainer
|
import app.revanced.patches.youtube.utils.resourceid.bottomBarContainer
|
||||||
import app.revanced.patches.youtube.utils.resourceid.metaPanel
|
import app.revanced.patches.youtube.utils.resourceid.metaPanel
|
||||||
import app.revanced.patches.youtube.utils.resourceid.reelDynRemix
|
import app.revanced.patches.youtube.utils.resourceid.reelDynRemix
|
||||||
@ -158,9 +158,9 @@ private val shortsCustomActionsPatch = bytecodePatch(
|
|||||||
description = "shortsCustomActionsPatch"
|
description = "shortsCustomActionsPatch"
|
||||||
) {
|
) {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
bottomSheetRecyclerViewPatch,
|
|
||||||
lithoFilterPatch,
|
lithoFilterPatch,
|
||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
|
recyclerViewTreeObserverPatch,
|
||||||
toolBarHookPatch,
|
toolBarHookPatch,
|
||||||
videoIdPatch,
|
videoIdPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
@ -332,7 +332,7 @@ private val shortsCustomActionsPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bottomSheetRecyclerViewHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
recyclerViewTreeObserverHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package app.revanced.patches.youtube.utils
|
package app.revanced.patches.youtube.utils
|
||||||
|
|
||||||
import app.revanced.patches.youtube.player.components.playerComponentsPatch
|
import app.revanced.patches.youtube.player.components.playerComponentsPatch
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.autoNavPreviewStub
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.autoNavToggle
|
||||||
import app.revanced.patches.youtube.utils.resourceid.fadeDurationFast
|
import app.revanced.patches.youtube.utils.resourceid.fadeDurationFast
|
||||||
import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarColorizedBarPlayedColorDark
|
import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarColorizedBarPlayedColorDark
|
||||||
import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarPlayedNotHighlightedColor
|
import app.revanced.patches.youtube.utils.resourceid.inlineTimeBarPlayedNotHighlightedColor
|
||||||
import app.revanced.patches.youtube.utils.resourceid.insetOverlayViewLayout
|
import app.revanced.patches.youtube.utils.resourceid.insetOverlayViewLayout
|
||||||
import app.revanced.patches.youtube.utils.resourceid.menuItemView
|
import app.revanced.patches.youtube.utils.resourceid.menuItemView
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.playerControlNextButtonTouchArea
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.playerControlPreviousButtonTouchArea
|
||||||
import app.revanced.patches.youtube.utils.resourceid.scrimOverlay
|
import app.revanced.patches.youtube.utils.resourceid.scrimOverlay
|
||||||
import app.revanced.patches.youtube.utils.resourceid.seekUndoEduOverlayStub
|
import app.revanced.patches.youtube.utils.resourceid.seekUndoEduOverlayStub
|
||||||
import app.revanced.patches.youtube.utils.resourceid.totalTime
|
import app.revanced.patches.youtube.utils.resourceid.totalTime
|
||||||
@ -62,7 +66,8 @@ internal val layoutConstructorFingerprint = legacyFingerprint(
|
|||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
||||||
strings = listOf("1.0x")
|
strings = listOf("1.0x"),
|
||||||
|
literals = listOf(autoNavToggle, autoNavPreviewStub, playerControlPreviousButtonTouchArea, playerControlNextButtonTouchArea),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val playbackRateBottomSheetBuilderFingerprint = legacyFingerprint(
|
internal val playbackRateBottomSheetBuilderFingerprint = legacyFingerprint(
|
||||||
|
@ -15,7 +15,7 @@ internal object Constants {
|
|||||||
"18.48.39", // This is the last version that do not use Rolling Number.
|
"18.48.39", // This is the last version that do not use Rolling Number.
|
||||||
"19.05.36", // This is the last version with the least YouTube experimental flag.
|
"19.05.36", // This is the last version with the least YouTube experimental flag.
|
||||||
"19.16.39", // This is the last version where the 'Restore old seekbar thumbnails' setting works.
|
"19.16.39", // This is the last version where the 'Restore old seekbar thumbnails' setting works.
|
||||||
"19.38.41", // This is the latest version supported by the RVX patch.
|
"19.44.39", // This is the latest version supported by the RVX patch.
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -10,9 +10,11 @@ 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 patches may be broken, so set this value to FALSE.
|
* In this case, some of patches may be broken, so set this value to FALSE.
|
||||||
*/
|
*/
|
||||||
|
internal const val CAIRO_FRAGMENT_FEATURE_FLAG = 45532100L
|
||||||
|
|
||||||
internal val carioFragmentConfigFingerprint = legacyFingerprint(
|
internal val carioFragmentConfigFingerprint = legacyFingerprint(
|
||||||
name = "carioFragmentConfigFingerprint",
|
name = "carioFragmentConfigFingerprint",
|
||||||
returnType = "Z",
|
returnType = "Z",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
literals = listOf(45532100L),
|
literals = listOf(CAIRO_FRAGMENT_FEATURE_FLAG),
|
||||||
)
|
)
|
||||||
|
@ -4,14 +4,21 @@ import app.revanced.util.fingerprint.legacyFingerprint
|
|||||||
import app.revanced.util.or
|
import app.revanced.util.or
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
internal val bottomSheetRecyclerViewBuilderFingerprint = legacyFingerprint(
|
internal const val RECYCLER_VIEW_BUILDER_FEATURE_FLAG = 45382015L
|
||||||
name = "bottomSheetRecyclerViewBuilderFingerprint",
|
|
||||||
literals = listOf(45382015L),
|
internal val recyclerViewBuilderFingerprint = legacyFingerprint(
|
||||||
|
name = "recyclerViewBuilderFingerprint",
|
||||||
|
literals = listOf(RECYCLER_VIEW_BUILDER_FEATURE_FLAG),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val recyclerViewTreeObserverFingerprint = legacyFingerprint(
|
internal val recyclerViewTreeObserverFingerprint = legacyFingerprint(
|
||||||
name = "recyclerViewTreeObserverFingerprint",
|
name = "recyclerViewTreeObserverFingerprint",
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
strings = listOf("LithoRVSLCBinder")
|
strings = listOf("LithoRVSLCBinder"),
|
||||||
|
customFingerprint = { method, _ ->
|
||||||
|
val parameterTypes = method.parameterTypes
|
||||||
|
parameterTypes.size > 2 &&
|
||||||
|
parameterTypes[1] == "Landroid/support/v7/widget/RecyclerView;"
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,6 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
import app.revanced.util.fingerprint.resolvable
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
@ -15,29 +14,27 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
|||||||
private lateinit var recyclerViewTreeObserverMutableMethod: MutableMethod
|
private lateinit var recyclerViewTreeObserverMutableMethod: MutableMethod
|
||||||
private var recyclerViewTreeObserverInsertIndex = 0
|
private var recyclerViewTreeObserverInsertIndex = 0
|
||||||
|
|
||||||
val bottomSheetRecyclerViewPatch = bytecodePatch(
|
val recyclerViewTreeObserverPatch = bytecodePatch(
|
||||||
description = "bottomSheetRecyclerViewPatch"
|
description = "recyclerViewTreeObserverPatch"
|
||||||
) {
|
) {
|
||||||
execute {
|
execute {
|
||||||
/**
|
/**
|
||||||
* If this value is false, OldQualityLayoutPatch and OldSpeedLayoutPatch will not work.
|
* If this value is false, RecyclerViewTreeObserver is not initialized.
|
||||||
* This value is usually true so this patch is not strictly necessary,
|
* This value is usually true so this patch is not strictly necessary,
|
||||||
* But in very rare cases this value may be false.
|
* But in very rare cases this value may be false.
|
||||||
* Therefore, we need to force this to be true.
|
* Therefore, we need to force this to be true.
|
||||||
*/
|
*/
|
||||||
if (bottomSheetRecyclerViewBuilderFingerprint.resolvable()) {
|
recyclerViewBuilderFingerprint.injectLiteralInstructionBooleanCall(
|
||||||
bottomSheetRecyclerViewBuilderFingerprint.injectLiteralInstructionBooleanCall(
|
RECYCLER_VIEW_BUILDER_FEATURE_FLAG,
|
||||||
45382015L,
|
"0x1"
|
||||||
"0x1"
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
recyclerViewTreeObserverFingerprint.methodOrThrow().apply {
|
recyclerViewTreeObserverFingerprint.methodOrThrow().apply {
|
||||||
recyclerViewTreeObserverMutableMethod = this
|
recyclerViewTreeObserverMutableMethod = this
|
||||||
|
|
||||||
val onDrawListenerIndex = indexOfFirstInstructionOrThrow {
|
val onDrawListenerIndex = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.IPUT_OBJECT
|
opcode == Opcode.IPUT_OBJECT &&
|
||||||
&& getReference<FieldReference>()?.type == "Landroid/view/ViewTreeObserver${'$'}OnDrawListener;"
|
getReference<FieldReference>()?.type == "Landroid/view/ViewTreeObserver${'$'}OnDrawListener;"
|
||||||
}
|
}
|
||||||
recyclerViewTreeObserverInsertIndex =
|
recyclerViewTreeObserverInsertIndex =
|
||||||
indexOfFirstInstructionReversedOrThrow(onDrawListenerIndex, Opcode.CHECK_CAST) + 1
|
indexOfFirstInstructionReversedOrThrow(onDrawListenerIndex, Opcode.CHECK_CAST) + 1
|
||||||
@ -45,7 +42,7 @@ val bottomSheetRecyclerViewPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bottomSheetRecyclerViewHook(descriptor: String) =
|
fun recyclerViewTreeObserverHook(descriptor: String) =
|
||||||
recyclerViewTreeObserverMutableMethod.addInstruction(
|
recyclerViewTreeObserverMutableMethod.addInstruction(
|
||||||
recyclerViewTreeObserverInsertIndex++,
|
recyclerViewTreeObserverInsertIndex++,
|
||||||
"invoke-static/range { p2 .. p2 }, $descriptor"
|
"invoke-static/range { p2 .. p2 }, $descriptor"
|
@ -134,14 +134,16 @@ var modernMiniPlayerRewindButton = -1L
|
|||||||
private set
|
private set
|
||||||
var musicAppDeeplinkButtonView = -1L
|
var musicAppDeeplinkButtonView = -1L
|
||||||
private set
|
private set
|
||||||
var notice = -1L
|
|
||||||
private set
|
|
||||||
var notificationBigPictureIconWidth = -1L
|
var notificationBigPictureIconWidth = -1L
|
||||||
private set
|
private set
|
||||||
var offlineActionsVideoDeletedUndoSnackbarText = -1L
|
var offlineActionsVideoDeletedUndoSnackbarText = -1L
|
||||||
private set
|
private set
|
||||||
var playerCollapseButton = -1L
|
var playerCollapseButton = -1L
|
||||||
private set
|
private set
|
||||||
|
var playerControlPreviousButtonTouchArea = -1L
|
||||||
|
private set
|
||||||
|
var playerControlNextButtonTouchArea = -1L
|
||||||
|
private set
|
||||||
var playerVideoTitleView = -1L
|
var playerVideoTitleView = -1L
|
||||||
private set
|
private set
|
||||||
var posterArtWidthDefault = -1L
|
var posterArtWidthDefault = -1L
|
||||||
@ -478,10 +480,6 @@ internal val sharedResourceIdPatch = resourcePatch(
|
|||||||
ID,
|
ID,
|
||||||
"music_app_deeplink_button_view"
|
"music_app_deeplink_button_view"
|
||||||
]
|
]
|
||||||
notice = resourceMappings[
|
|
||||||
ID,
|
|
||||||
"notice"
|
|
||||||
]
|
|
||||||
notificationBigPictureIconWidth = resourceMappings[
|
notificationBigPictureIconWidth = resourceMappings[
|
||||||
DIMEN,
|
DIMEN,
|
||||||
"notification_big_picture_icon_width"
|
"notification_big_picture_icon_width"
|
||||||
@ -494,6 +492,14 @@ internal val sharedResourceIdPatch = resourcePatch(
|
|||||||
ID,
|
ID,
|
||||||
"player_collapse_button"
|
"player_collapse_button"
|
||||||
]
|
]
|
||||||
|
playerControlPreviousButtonTouchArea = resourceMappings[
|
||||||
|
ID,
|
||||||
|
"player_control_previous_button_touch_area"
|
||||||
|
]
|
||||||
|
playerControlNextButtonTouchArea = resourceMappings[
|
||||||
|
ID,
|
||||||
|
"player_control_next_button_touch_area"
|
||||||
|
]
|
||||||
playerVideoTitleView = resourceMappings[
|
playerVideoTitleView = resourceMappings[
|
||||||
ID,
|
ID,
|
||||||
"player_video_title_view"
|
"player_video_title_view"
|
||||||
|
@ -19,8 +19,8 @@ import app.revanced.patches.youtube.utils.flyoutmenu.flyoutMenuHookPatch
|
|||||||
import app.revanced.patches.youtube.utils.patch.PatchList.VIDEO_PLAYBACK
|
import app.revanced.patches.youtube.utils.patch.PatchList.VIDEO_PLAYBACK
|
||||||
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.utils.qualityMenuViewInflateFingerprint
|
import app.revanced.patches.youtube.utils.qualityMenuViewInflateFingerprint
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewHook
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverPatch
|
||||||
import app.revanced.patches.youtube.utils.recyclerview.bottomSheetRecyclerViewPatch
|
import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverHook
|
||||||
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
||||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
||||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||||
@ -80,7 +80,6 @@ val videoPlaybackPatch = bytecodePatch(
|
|||||||
|
|
||||||
dependsOn(
|
dependsOn(
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
bottomSheetRecyclerViewPatch,
|
|
||||||
customPlaybackSpeedPatch(
|
customPlaybackSpeedPatch(
|
||||||
"$VIDEO_PATH/CustomPlaybackSpeedPatch;",
|
"$VIDEO_PATH/CustomPlaybackSpeedPatch;",
|
||||||
8.0f
|
8.0f
|
||||||
@ -88,6 +87,7 @@ val videoPlaybackPatch = bytecodePatch(
|
|||||||
flyoutMenuHookPatch,
|
flyoutMenuHookPatch,
|
||||||
lithoFilterPatch,
|
lithoFilterPatch,
|
||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
|
recyclerViewTreeObserverPatch,
|
||||||
shortsPlaybackPatch,
|
shortsPlaybackPatch,
|
||||||
videoIdPatch,
|
videoIdPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
@ -102,7 +102,7 @@ val videoPlaybackPatch = bytecodePatch(
|
|||||||
|
|
||||||
// region patch for custom playback speed
|
// region patch for custom playback speed
|
||||||
|
|
||||||
bottomSheetRecyclerViewHook("$EXTENSION_CUSTOM_PLAYBACK_SPEED_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
recyclerViewTreeObserverHook("$EXTENSION_CUSTOM_PLAYBACK_SPEED_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
||||||
addLithoFilter(PLAYBACK_SPEED_MENU_FILTER_CLASS_DESCRIPTOR)
|
addLithoFilter(PLAYBACK_SPEED_MENU_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@ -249,7 +249,7 @@ val videoPlaybackPatch = bytecodePatch(
|
|||||||
} ?: throw PatchException("Failed to find onItemClick method")
|
} ?: throw PatchException("Failed to find onItemClick method")
|
||||||
}
|
}
|
||||||
|
|
||||||
bottomSheetRecyclerViewHook("$EXTENSION_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
recyclerViewTreeObserverHook("$EXTENSION_RESTORE_OLD_VIDEO_QUALITY_MENU_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V")
|
||||||
addLithoFilter(VIDEO_QUALITY_MENU_FILTER_CLASS_DESCRIPTOR)
|
addLithoFilter(VIDEO_QUALITY_MENU_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user