mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-29 21:30:19 +02:00
feat(YouTube - Remove background playback restrictions): Add PiP mode support in Shorts
This commit is contained in:
parent
10b5119afc
commit
9e50e0d874
@ -1,12 +1,24 @@
|
|||||||
package app.revanced.extension.youtube.patches.misc;
|
package app.revanced.extension.youtube.patches.misc;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BackgroundPlaybackPatch {
|
public class BackgroundPlaybackPatch {
|
||||||
|
|
||||||
public static boolean allowBackgroundPlayback(boolean original) {
|
/**
|
||||||
return original || ShortsPlayerState.getCurrent().isClosed();
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean isBackgroundPlaybackAllowed(boolean original) {
|
||||||
|
if (original) return true;
|
||||||
|
return ShortsPlayerState.getCurrent().isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean isBackgroundShortsPlaybackAllowed(boolean original) {
|
||||||
|
return !Settings.DISABLE_SHORTS_BACKGROUND_PLAYBACK.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -419,6 +419,7 @@ public class Settings extends BaseSettings {
|
|||||||
|
|
||||||
// PreferenceScreen: Shorts
|
// PreferenceScreen: Shorts
|
||||||
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", TRUE);
|
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", TRUE);
|
||||||
|
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_disable_shorts_background_playback", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_FLOATING_BUTTON = new BooleanSetting("revanced_hide_shorts_floating_button", TRUE);
|
public static final BooleanSetting HIDE_SHORTS_FLOATING_BUTTON = new BooleanSetting("revanced_hide_shorts_floating_button", TRUE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_SHELF = new BooleanSetting("revanced_hide_shorts_shelf", TRUE, true);
|
public static final BooleanSetting HIDE_SHORTS_SHELF = new BooleanSetting("revanced_hide_shorts_shelf", TRUE, true);
|
||||||
public static final BooleanSetting HIDE_SHORTS_SHELF_CHANNEL = new BooleanSetting("revanced_hide_shorts_shelf_channel", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_SHELF_CHANNEL = new BooleanSetting("revanced_hide_shorts_shelf_channel", FALSE);
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package app.revanced.patches.youtube.misc.backgroundplayback
|
package app.revanced.patches.youtube.misc.backgroundplayback
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
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.MISC_PATH
|
import app.revanced.patches.youtube.utils.extension.Constants.MISC_PATH
|
||||||
@ -11,16 +9,19 @@ import app.revanced.patches.youtube.utils.patch.PatchList.REMOVE_BACKGROUND_PLAY
|
|||||||
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
||||||
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.addInstructionsAtControlFlowLabel
|
||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.fingerprint.matchOrThrow
|
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.fingerprint.originalMethodOrThrow
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
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.ReferenceInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"$MISC_PATH/BackgroundPlaybackPatch;"
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val backgroundPlaybackPatch = bytecodePatch(
|
val backgroundPlaybackPatch = bytecodePatch(
|
||||||
REMOVE_BACKGROUND_PLAYBACK_RESTRICTIONS.title,
|
REMOVE_BACKGROUND_PLAYBACK_RESTRICTIONS.title,
|
||||||
@ -35,69 +36,54 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
|
|
||||||
execute {
|
execute {
|
||||||
|
|
||||||
backgroundPlaybackManagerFingerprint.methodOrThrow().apply {
|
arrayOf(
|
||||||
findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
|
backgroundPlaybackManagerFingerprint to "isBackgroundPlaybackAllowed",
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
backgroundPlaybackManagerShortsFingerprint to "isBackgroundShortsPlaybackAllowed",
|
||||||
|
).forEach { (fingerprint, integrationsMethod) ->
|
||||||
|
fingerprint.methodOrThrow().apply {
|
||||||
|
findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
// Replace to preserve control flow label.
|
addInstructionsAtControlFlowLabel(
|
||||||
replaceInstruction(
|
index,
|
||||||
index,
|
|
||||||
"invoke-static { v$register }, $MISC_PATH/BackgroundPlaybackPatch;->allowBackgroundPlayback(Z)Z"
|
|
||||||
)
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
index + 1,
|
|
||||||
"""
|
|
||||||
move-result v$register
|
|
||||||
return v$register
|
|
||||||
"""
|
"""
|
||||||
)
|
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$integrationsMethod(Z)Z
|
||||||
|
move-result v$register
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable background playback option in YouTube settings
|
// Enable background playback option in YouTube settings
|
||||||
backgroundPlaybackSettingsFingerprint.methodOrThrow().apply {
|
backgroundPlaybackSettingsFingerprint.originalMethodOrThrow().apply {
|
||||||
val booleanCalls = implementation!!.instructions.withIndex()
|
val booleanCalls = instructions.withIndex().filter {
|
||||||
.filter { instruction ->
|
it.value.getReference<MethodReference>()?.returnType == "Z"
|
||||||
((instruction.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val booleanIndex = booleanCalls.elementAt(1).index
|
val settingsBooleanIndex = booleanCalls.elementAt(1).index
|
||||||
val booleanMethod = getWalkerMethod(booleanIndex)
|
val settingsBooleanMethod by navigate(this).to(settingsBooleanIndex)
|
||||||
|
|
||||||
booleanMethod.addInstructions(
|
settingsBooleanMethod.returnEarly(true)
|
||||||
0, """
|
|
||||||
const/4 v0, 0x1
|
|
||||||
return v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force allowing background play for Shorts.
|
||||||
|
shortsBackgroundPlaybackFeatureFlagFingerprint.methodOrThrow().returnEarly(true)
|
||||||
|
|
||||||
// Force allowing background play for videos labeled for kids.
|
// Force allowing background play for videos labeled for kids.
|
||||||
kidsBackgroundPlaybackPolicyControllerFingerprint.methodOrThrow(
|
kidsBackgroundPlaybackPolicyControllerFingerprint.methodOrThrow(
|
||||||
kidsBackgroundPlaybackPolicyControllerParentFingerprint
|
kidsBackgroundPlaybackPolicyControllerParentFingerprint
|
||||||
).addInstruction(
|
).returnEarly()
|
||||||
0,
|
|
||||||
"return-void"
|
|
||||||
)
|
|
||||||
|
|
||||||
pipControllerFingerprint.matchOrThrow().let {
|
|
||||||
val targetMethod =
|
|
||||||
it.getWalkerMethod(it.patternMatch!!.endIndex)
|
|
||||||
|
|
||||||
targetMethod.apply {
|
|
||||||
val targetRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
1,
|
|
||||||
"const/4 v$targetRegister, 0x1"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// region add settings
|
// region add settings
|
||||||
|
|
||||||
addPreference(REMOVE_BACKGROUND_PLAYBACK_RESTRICTIONS)
|
addPreference(
|
||||||
|
arrayOf(
|
||||||
|
"PREFERENCE_SCREEN: SHORTS",
|
||||||
|
"SETTINGS: DISABLE_SHORTS_BACKGROUND_PLAYBACK"
|
||||||
|
),
|
||||||
|
REMOVE_BACKGROUND_PLAYBACK_RESTRICTIONS
|
||||||
|
)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -56,14 +56,18 @@ internal val kidsBackgroundPlaybackPolicyControllerParentFingerprint = legacyFin
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val pipControllerFingerprint = legacyFingerprint(
|
internal val backgroundPlaybackManagerShortsFingerprint = legacyFingerprint(
|
||||||
name = "pipControllerFingerprint",
|
name = "backgroundPlaybackManagerShortsFingerprint",
|
||||||
returnType = "V",
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
returnType = "Z",
|
||||||
parameters = emptyList(),
|
parameters = listOf("L"),
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.IF_NEZ,
|
|
||||||
Opcode.INVOKE_DIRECT
|
|
||||||
),
|
|
||||||
literals = listOf(151635310L),
|
literals = listOf(151635310L),
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val shortsBackgroundPlaybackFeatureFlagFingerprint = legacyFingerprint(
|
||||||
|
name = "shortsBackgroundPlaybackFeatureFlagFingerprint",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
returnType = "Z",
|
||||||
|
parameters = emptyList(),
|
||||||
|
literals = listOf(45415425L),
|
||||||
)
|
)
|
@ -1196,6 +1196,9 @@ The Expand video description option may not work if the entered string does not
|
|||||||
<!-- PreferenceScreen: Shorts -->
|
<!-- PreferenceScreen: Shorts -->
|
||||||
<string name="revanced_preference_screen_shorts_title">Shorts</string>
|
<string name="revanced_preference_screen_shorts_title">Shorts</string>
|
||||||
|
|
||||||
|
<string name="revanced_disable_shorts_background_playback_title">Disable Shorts background play</string>
|
||||||
|
<string name="revanced_disable_shorts_background_playback_summary_on">Shorts background play is disabled.</string>
|
||||||
|
<string name="revanced_disable_shorts_background_playback_summary_off">Shorts background play is enabled.</string>
|
||||||
<string name="revanced_disable_resuming_shorts_player_title">Disable resuming Shorts player</string>
|
<string name="revanced_disable_resuming_shorts_player_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_player_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_player_summary_off">Shorts player will resume on app startup.</string>
|
||||||
|
@ -596,6 +596,9 @@
|
|||||||
<SwitchPreference android:title="@string/revanced_replace_channel_handle_title" android:key="revanced_replace_channel_handle" android:summaryOn="@string/revanced_replace_channel_handle_summary_on" android:summaryOff="@string/revanced_replace_channel_handle_summary_off" />
|
<SwitchPreference android:title="@string/revanced_replace_channel_handle_title" android:key="revanced_replace_channel_handle" android:summaryOn="@string/revanced_replace_channel_handle_summary_on" android:summaryOff="@string/revanced_replace_channel_handle_summary_off" />
|
||||||
</PreferenceScreen>SETTINGS: SHORTS_COMPONENTS -->
|
</PreferenceScreen>SETTINGS: SHORTS_COMPONENTS -->
|
||||||
|
|
||||||
|
<!-- SETTINGS: DISABLE_SHORTS_BACKGROUND_PLAYBACK
|
||||||
|
<SwitchPreference android:title="@string/revanced_disable_shorts_background_playback_title" android:key="revanced_disable_shorts_background_playback" android:summaryOn="@string/revanced_disable_shorts_background_playback_summary_on" android:summaryOff="@string/revanced_disable_shorts_background_playback_summary_off" />SETTINGS: DISABLE_SHORTS_BACKGROUND_PLAYBACK -->
|
||||||
|
|
||||||
<!-- SETTINGS: DISABLE_RESUMING_SHORTS_PLAYER
|
<!-- SETTINGS: DISABLE_RESUMING_SHORTS_PLAYER
|
||||||
<SwitchPreference android:title="@string/revanced_disable_resuming_shorts_player_title" android:key="revanced_disable_resuming_shorts_player" android:summaryOn="@string/revanced_disable_resuming_shorts_player_summary_on" android:summaryOff="@string/revanced_disable_resuming_shorts_player_summary_off" />SETTINGS: DISABLE_RESUMING_SHORTS_PLAYER -->
|
<SwitchPreference android:title="@string/revanced_disable_resuming_shorts_player_title" android:key="revanced_disable_resuming_shorts_player" android:summaryOn="@string/revanced_disable_resuming_shorts_player_summary_on" android:summaryOff="@string/revanced_disable_resuming_shorts_player_summary_off" />SETTINGS: DISABLE_RESUMING_SHORTS_PLAYER -->
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user