fix(YouTube - Remove background playback restriction): Play/Pause button not working in PiP mode https://github.com/inotia00/ReVanced_Extended/issues/2764

This commit is contained in:
inotia00 2025-02-07 16:00:16 +09:00
parent 6f1fc6116b
commit 38949e12fd
3 changed files with 93 additions and 22 deletions

View File

@ -18,16 +18,6 @@ public class BackgroundPlaybackPatch {
return ShortsPlayerState.getCurrent().isClosed();
}
/**
* Injection point.
*/
public static boolean isBackgroundShortsPlaybackAllowed() {
if (PlayerType.getCurrent().isNoneHiddenOrMinimized()) {
return !DISABLE_SHORTS_BACKGROUND_PLAYBACK.get();
}
return false;
}
/**
* Injection point.
*/

View File

@ -1,6 +1,6 @@
package app.revanced.patches.youtube.misc.backgroundplayback
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.patch.bytecodePatch
@ -8,10 +8,14 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
import app.revanced.patches.youtube.utils.extension.Constants.MISC_PATH
import app.revanced.patches.youtube.utils.patch.PatchList.REMOVE_BACKGROUND_PLAYBACK_RESTRICTIONS
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
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.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.addInstructionsAtControlFlowLabel
import app.revanced.util.findInstructionIndicesReversedOrThrow
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
import app.revanced.util.fingerprint.matchOrThrow
import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.fingerprint.originalMethodOrThrow
import app.revanced.util.getReference
@ -33,6 +37,7 @@ val backgroundPlaybackPatch = bytecodePatch(
dependsOn(
playerTypeHookPatch,
settingsPatch,
versionCheckPatch,
)
execute {
@ -69,18 +74,31 @@ val backgroundPlaybackPatch = bytecodePatch(
}
// Force allowing background play for Shorts.
shortsBackgroundPlaybackFeatureFlagFingerprint.methodOrThrow().addInstructionsWithLabels(
0,
"""
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->isBackgroundShortsPlaybackAllowed()Z
move-result v0
if-eqz v0, :disabled
return v0
:disabled
nop
"""
shortsBackgroundPlaybackFeatureFlagFingerprint.injectLiteralInstructionBooleanCall(
SHORTS_BACKGROUND_PLAYBACK_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->isBackgroundShortsPlaybackAllowed(Z)Z"
)
// Fix PiP mode issue.
if (is_19_34_or_greater) {
arrayOf(
backgroundPlaybackManagerCairoFragmentPrimaryFingerprint,
backgroundPlaybackManagerCairoFragmentSecondaryFingerprint
).forEach { fingerprint ->
fingerprint.matchOrThrow(backgroundPlaybackManagerCairoFragmentParentFingerprint).let {
it.method.apply {
val insertIndex = it.patternMatch!!.startIndex + 4
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex,
"const/4 v$insertRegister, 0x0"
)
}
}
}
}
// Force allowing background play for videos labeled for kids.
kidsBackgroundPlaybackPolicyControllerFingerprint.methodOrThrow(
kidsBackgroundPlaybackPolicyControllerParentFingerprint

View File

@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.backgroundplayback
import app.revanced.patches.youtube.utils.PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.fix.cairo.cairoFragmentConfigFingerprint
import app.revanced.patches.youtube.utils.resourceid.backgroundCategory
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference
@ -64,10 +65,72 @@ internal val backgroundPlaybackManagerShortsFingerprint = legacyFingerprint(
literals = listOf(151635310L),
)
internal val backgroundPlaybackManagerCairoFragmentParentFingerprint = legacyFingerprint(
name = "backgroundPlaybackManagerCairoFragmentParentFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = emptyList(),
strings = listOf("yt_android_settings"),
customFingerprint = { method, _ ->
method.definingClass != "Lcom/google/android/apps/youtube/app/settings/AboutPrefsFragment;"
}
)
/**
* Matches using the class found in [backgroundPlaybackManagerCairoFragmentParentFingerprint].
*
* In this method, the value of the cairoFragmentConfig - [cairoFragmentConfigFingerprint] - must be disabled.
* If not, sometimes the pause / play button may not work when entering the PIP mode.
* See [ReVanced_Extended#2764](https://github.com/inotia00/ReVanced_Extended/issues/2764).
*/
internal val backgroundPlaybackManagerCairoFragmentPrimaryFingerprint = legacyFingerprint(
name = "backgroundPlaybackManagerCairoFragmentPrimaryFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = emptyList(),
opcodes = listOf(
Opcode.INVOKE_SUPER,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL, // Method of [cairoFragmentConfigFingerprint]
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.CONST_4,
Opcode.IPUT_OBJECT,
),
)
/**
* Matches using the class found in [backgroundPlaybackManagerCairoFragmentParentFingerprint].
*
* In this method, the value of the cairoFragmentConfig - [cairoFragmentConfigFingerprint] - must be disabled.
* If not, sometimes the pause / play button may not work when entering the PIP mode.
* See [ReVanced_Extended#2764](https://github.com/inotia00/ReVanced_Extended/issues/2764).
*/
internal val backgroundPlaybackManagerCairoFragmentSecondaryFingerprint = legacyFingerprint(
name = "backgroundPlaybackManagerCairoFragmentSecondaryFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = emptyList(),
opcodes = listOf(
Opcode.INVOKE_SUPER,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL, // Method of [cairoFragmentConfigFingerprint]
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.NEW_INSTANCE,
),
)
internal const val SHORTS_BACKGROUND_PLAYBACK_FEATURE_FLAG = 45415425L
internal val shortsBackgroundPlaybackFeatureFlagFingerprint = legacyFingerprint(
name = "shortsBackgroundPlaybackFeatureFlagFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z",
parameters = emptyList(),
literals = listOf(45415425L),
literals = listOf(SHORTS_BACKGROUND_PLAYBACK_FEATURE_FLAG),
)