fix(YouTube - Disable Shorts resuming on startup): Resolve patch not working on experimental versions
Co-authored-by: ILoveOpenSourceApplications <117499019+iloveopensourceapplications@users.noreply.github.com>
This commit is contained in:
parent
53318c48ee
commit
58898b92fe
7 changed files with 130 additions and 87 deletions
|
|
@ -0,0 +1,21 @@
|
||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class DisableResumingShortsOnStartupPatch {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean disableResumingShortsOnStartup() {
|
||||||
|
return Settings.DISABLE_RESUMING_SHORTS_ON_STARTUP.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean disableResumingShortsOnStartup(boolean original) {
|
||||||
|
return original && !Settings.DISABLE_RESUMING_SHORTS_ON_STARTUP.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
package app.revanced.extension.youtube.patches;
|
|
||||||
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class DisableResumingStartupShortsPlayerPatch {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static boolean disableResumingStartupShortsPlayer() {
|
|
||||||
return Settings.DISABLE_RESUMING_SHORTS_PLAYER.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static boolean disableResumingStartupShortsPlayer(boolean original) {
|
|
||||||
return original && !Settings.DISABLE_RESUMING_SHORTS_PLAYER.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -324,7 +324,7 @@ public class Settings extends YouTubeAndMusicSettings {
|
||||||
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
|
||||||
|
|
||||||
// Shorts
|
// Shorts
|
||||||
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
|
public static final BooleanSetting DISABLE_RESUMING_SHORTS_ON_STARTUP = new BooleanSetting("revanced_disable_resuming_shorts_on_startup", FALSE);
|
||||||
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
||||||
public static final EnumSetting<ShortsPlayerType> SHORTS_PLAYER_TYPE = new EnumSetting<>("revanced_shorts_player_type", ShortsPlayerType.SHORTS_PLAYER);
|
public static final EnumSetting<ShortsPlayerType> SHORTS_PLAYER_TYPE = new EnumSetting<>("revanced_shorts_player_type", ShortsPlayerType.SHORTS_PLAYER);
|
||||||
public static final BooleanSetting HIDE_SHORTS_AI_BUTTON = new BooleanSetting("revanced_hide_shorts_ai_button", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_AI_BUTTON = new BooleanSetting("revanced_hide_shorts_ai_button", FALSE);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package app.revanced.patches.youtube.layout.startupshortsreset
|
package app.revanced.patches.youtube.layout.shortsresuming
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.getInstruction
|
import app.revanced.patcher.extensions.getInstruction
|
||||||
|
|
@ -18,10 +18,11 @@ import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
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.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch;"
|
"Lapp/revanced/extension/youtube/patches/DisableResumingShortsOnStartupPatch;"
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val disableResumingShortsOnStartupPatch = bytecodePatch(
|
val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||||
|
|
@ -44,24 +45,33 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||||
"20.37.48",
|
"20.37.48",
|
||||||
"20.40.45",
|
"20.40.45",
|
||||||
"20.44.38"
|
"20.44.38"
|
||||||
// This patch is obsolete with 21.03 because YT seems to have
|
|
||||||
// removed resuming Shorts functionality.
|
|
||||||
// TODO: Before adding 21.03+, merge this patch into `Hide Shorts component`
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
// 21.03+ seems to no longer have resuming Shorts functionality.
|
addResources("youtube", "layout.shortsresuming.disableResumingShortsOnStartupPatch")
|
||||||
if (is_21_03_or_greater) return@apply
|
|
||||||
|
|
||||||
addResources("youtube", "layout.startupshortsreset.disableResumingShortsOnStartupPatch")
|
|
||||||
|
|
||||||
PreferenceScreen.SHORTS.addPreferences(
|
PreferenceScreen.SHORTS.addPreferences(
|
||||||
SwitchPreference("revanced_disable_resuming_shorts_player"),
|
SwitchPreference("revanced_disable_resuming_shorts_on_startup"),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (is_20_03_or_greater) {
|
if (is_21_03_or_greater) {
|
||||||
userWasInShortsAlternativeMethodMatch.let {
|
userWasInShortsEvaluateMethodMatch.let {
|
||||||
|
it.method.apply {
|
||||||
|
val instruction = getInstruction<RegisterRangeInstruction>(it[0])
|
||||||
|
val zMRegister = instruction.startRegister + 2
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
it[0],
|
||||||
|
"""
|
||||||
|
invoke-static { v$zMRegister }, ${EXTENSION_CLASS_DESCRIPTOR}->disableResumingShortsOnStartup(Z)Z
|
||||||
|
move-result v$zMRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (is_20_03_or_greater) {
|
||||||
|
userWasInShortsListenerMethodMatch.let {
|
||||||
it.method.apply {
|
it.method.apply {
|
||||||
val insertIndex = it[2] + 1
|
val insertIndex = it[2] + 1
|
||||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
@ -69,7 +79,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingShortsOnStartup(Z)Z
|
||||||
move-result v$register
|
move-result v$register
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
@ -87,7 +97,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||||
addInstructionsAtControlFlowLabel(
|
addInstructionsAtControlFlowLabel(
|
||||||
listenableInstructionIndex,
|
listenableInstructionIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingShortsOnStartup()Z
|
||||||
move-result v$freeRegister
|
move-result v$freeRegister
|
||||||
if-eqz v$freeRegister, :show_startup_shorts_player
|
if-eqz v$freeRegister, :show_startup_shorts_player
|
||||||
return-void
|
return-void
|
||||||
|
|
@ -101,7 +111,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
|
||||||
userWasInShortsConfigMethod.addInstructions(
|
userWasInShortsConfigMethod.addInstructions(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableResumingShortsOnStartup()Z
|
||||||
move-result v0
|
move-result v0
|
||||||
if-eqz v0, :show
|
if-eqz v0, :show
|
||||||
const/4 v0, 0x0
|
const/4 v0, 0x0
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package app.revanced.patches.youtube.layout.shortsresuming
|
||||||
|
|
||||||
|
import app.revanced.patcher.*
|
||||||
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import kotlin.collections.all
|
||||||
|
import kotlin.collections.zip
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 21.03+
|
||||||
|
*/
|
||||||
|
internal val BytecodePatchContext.userWasInShortsEvaluateMethodMatch by composingFirstMethod {
|
||||||
|
val method1ParametersPrefix = listOf("L", "Z", "Z", "L", "Z")
|
||||||
|
val method2ParametersPrefix = listOf("L", "L", "L", "L", "L", "I")
|
||||||
|
|
||||||
|
instructions(
|
||||||
|
allOf(
|
||||||
|
Opcode.INVOKE_DIRECT_RANGE(),
|
||||||
|
method {
|
||||||
|
name == "<init>" && parameterTypes.zip(method1ParametersPrefix)
|
||||||
|
.all { (a, b) -> a.startsWith(b) }
|
||||||
|
}
|
||||||
|
),
|
||||||
|
afterAtMost(
|
||||||
|
50, allOf(
|
||||||
|
Opcode.INVOKE_DIRECT_RANGE(),
|
||||||
|
method {
|
||||||
|
name == "<init>" && parameterTypes.zip(method2ParametersPrefix)
|
||||||
|
.all { (a, b) -> a.startsWith(b) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 20.02+
|
||||||
|
*/
|
||||||
|
internal
|
||||||
|
val BytecodePatchContext.userWasInShortsListenerMethodMatch by composingFirstMethod {
|
||||||
|
returnType("V")
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameterTypes("Ljava/lang/Object;")
|
||||||
|
instructions(
|
||||||
|
allOf(Opcode.CHECK_CAST(), type("Ljava/lang/Boolean;")),
|
||||||
|
after(method { toString() == "Ljava/lang/Boolean;->booleanValue()Z" }),
|
||||||
|
after(Opcode.MOVE_RESULT()),
|
||||||
|
// 20.40+ string was merged into another string and is a partial match.
|
||||||
|
afterAtMost(30, "ShortsStartup SetUserWasInShortsListener"(String::contains)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre 20.02
|
||||||
|
*/
|
||||||
|
internal
|
||||||
|
val BytecodePatchContext.userWasInShortsLegacyMethod by gettingFirstMethodDeclaratively {
|
||||||
|
returnType("V")
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
parameterTypes("Ljava/lang/Object;")
|
||||||
|
instructions(
|
||||||
|
"Failed to read user_was_in_shorts proto after successful warmup"(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 18.15.40+
|
||||||
|
*/
|
||||||
|
internal
|
||||||
|
val BytecodePatchContext.userWasInShortsConfigMethod by gettingFirstMethodDeclaratively {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returnType("Z")
|
||||||
|
parameterTypes()
|
||||||
|
instructions(
|
||||||
|
45358360L(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package app.revanced.patches.youtube.layout.startupshortsreset
|
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 20.02+
|
|
||||||
*/
|
|
||||||
internal val BytecodePatchContext.userWasInShortsAlternativeMethodMatch by composingFirstMethod {
|
|
||||||
returnType("V")
|
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
|
||||||
parameterTypes("Ljava/lang/Object;")
|
|
||||||
instructions(
|
|
||||||
allOf(Opcode.CHECK_CAST(), type("Ljava/lang/Boolean;")),
|
|
||||||
after(method { toString() == "Ljava/lang/Boolean;->booleanValue()Z" }),
|
|
||||||
after(Opcode.MOVE_RESULT()),
|
|
||||||
// 20.40+ string was merged into another string and is a partial match.
|
|
||||||
afterAtMost(15, "userIsInShorts: "(String::contains)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pre 20.02
|
|
||||||
*/
|
|
||||||
internal val BytecodePatchContext.userWasInShortsLegacyMethod by gettingFirstMethodDeclaratively {
|
|
||||||
returnType("V")
|
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
|
||||||
parameterTypes("Ljava/lang/Object;")
|
|
||||||
instructions(
|
|
||||||
"Failed to read user_was_in_shorts proto after successful warmup"(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 18.15.40+
|
|
||||||
*/
|
|
||||||
internal val BytecodePatchContext.userWasInShortsConfigMethod by gettingFirstMethodDeclaratively {
|
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
|
||||||
returnType("Z")
|
|
||||||
parameterTypes()
|
|
||||||
instructions(
|
|
||||||
45358360L(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1490,10 +1490,10 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs.
|
||||||
Limitation: Using the back button on the toolbar may not work"</string>
|
Limitation: Using the back button on the toolbar may not work"</string>
|
||||||
<string name="revanced_change_start_page_always_summary_off">Start page is changed only on app startup</string>
|
<string name="revanced_change_start_page_always_summary_off">Start page is changed only on app startup</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
|
<patch id="layout.shortsresuming.disableResumingShortsOnStartupPatch">
|
||||||
<string name="revanced_disable_resuming_shorts_player_title">Disable resuming Shorts player</string>
|
<string name="revanced_disable_resuming_shorts_on_startup_title">Disable resuming Shorts player</string>
|
||||||
<string name="revanced_disable_resuming_shorts_player_summary_on">Shorts player will not resume on app startup</string>
|
<string name="revanced_disable_resuming_shorts_on_startup_summary_on">Shorts player will not resume on app startup</string>
|
||||||
<string name="revanced_disable_resuming_shorts_player_summary_off">Shorts player will resume on app startup</string>
|
<string name="revanced_disable_resuming_shorts_on_startup_summary_off">Shorts player will resume on app startup</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
||||||
<string name="revanced_shorts_player_type_title">Open Shorts with</string>
|
<string name="revanced_shorts_player_type_title">Open Shorts with</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue