From 490edc93d96dcc674a82802fab0e32cad5f43352 Mon Sep 17 00:00:00 2001 From: inotia00 Date: Sun, 5 Feb 2023 12:41:19 +0900 Subject: [PATCH] refactor: `Disable pip mode in shorts player` (Experimental Flags) setting now works on Android 12+ devices --- .../bytecode/fingerprints/PiPFingerprint.kt | 16 +++++ ...Fingerprint.kt => PiPParentFingerprint.kt} | 9 ++- .../patch/DisableShortsPiPBytecodePatch.kt | 64 +++++++------------ 3 files changed, 46 insertions(+), 43 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPFingerprint.kt rename src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/{DisableShortsPiPFingerprint.kt => PiPParentFingerprint.kt} (70%) diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPFingerprint.kt new file mode 100644 index 000000000..5216b71a0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.extended.shortspip.bytecode.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object PiPFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.IF_NE, + Opcode.CONST_4 + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/DisableShortsPiPFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPParentFingerprint.kt similarity index 70% rename from src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/DisableShortsPiPFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPParentFingerprint.kt index 62289c471..f26fa56aa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/DisableShortsPiPFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/fingerprints/PiPParentFingerprint.kt @@ -3,10 +3,15 @@ package app.revanced.patches.youtube.extended.shortspip.bytecode.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode -object DisableShortsPiPFingerprint : MethodFingerprint( - returnType = "L", +object PiPParentFingerprint : MethodFingerprint( + returnType = "V", access = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L"), + opcodes = listOf( + Opcode.SGET_OBJECT, + Opcode.NEW_INSTANCE + ), customFingerprint = { it.definingClass == "Lcom/google/android/apps/youtube/app/common/ui/pip/DefaultPipController;" } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/patch/DisableShortsPiPBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/patch/DisableShortsPiPBytecodePatch.kt index 0ff43486d..bea2afb7a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/patch/DisableShortsPiPBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/shortspip/bytecode/patch/DisableShortsPiPBytecodePatch.kt @@ -5,20 +5,17 @@ import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.extended.shortspip.bytecode.fingerprints.DisableShortsPiPFingerprint +import app.revanced.patches.youtube.extended.shortspip.bytecode.fingerprints.* import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.EXTENDED_PATH -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction35c +import org.jf.dexlib2.builder.instruction.BuilderInstruction21c import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Name("disable-shorts-pip-bytecode-patch") @@ -31,48 +28,33 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Version("0.0.1") class DisableShortsPiPBytecodePatch : BytecodePatch( listOf( - DisableShortsPiPFingerprint + PiPParentFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { - DisableShortsPiPFingerprint.result?.mutableMethod?.let { method -> + PiPParentFingerprint.result?.let { result -> + val targetIndex = result.scanResult.patternScanResult!!.endIndex + val targetTnstuction = result.mutableMethod.instruction(targetIndex) + val imageButtonClass = + context.findClass((targetTnstuction as BuilderInstruction21c) + .reference.toString())!! + .mutableClass - with (method.implementation!!) { - val invokeIndex = this.instructions.indexOfFirst { - it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal && - ((it as? BuilderInstruction35c)?.reference.toString() == - "$REFERENCE_DESCRIPTOR") + PiPFingerprint.also { it.resolve(context, imageButtonClass) }.result?.let { newResult -> + with (newResult.mutableMethod) { + val endIndex = newResult.scanResult.patternScanResult!!.endIndex + val register = (implementation!!.instructions[endIndex] as OneRegisterInstruction).registerA + this.addInstructions( + endIndex + 1, """ + invoke-static {v$register}, $EXTENDED_PATH/DisableShortsPiPPatch;->disableShortsPlayerPiP(Z)Z + move-result v$register + """ + ) } - val registerA = (method.instruction(invokeIndex + 1) as OneRegisterInstruction).registerA - - val registerC = (method.instruction(invokeIndex) as BuilderInstruction35c).registerC - val registerE = (method.instruction(invokeIndex) as BuilderInstruction35c).registerE - - method.addInstructions( - invokeIndex + 1,""" - invoke-static {}, $EXTENDED_PATH/DisableShortsPiPPatch;->disableShortsPlayerPiP()Z - move-result v$registerA - if-eqz v$registerA, :pip - goto :disablepip - :pip - invoke-virtual {v${registerC}, v${registerE}}, $REFERENCE_DESCRIPTOR - move-result v$registerA - """, listOf(ExternalLabel("disablepip", method.instruction(invokeIndex + 1))) - ) - method.removeInstruction(invokeIndex) - method.replaceInstruction( - invokeIndex + 6, "nop" - ) - - } - } ?: return DisableShortsPiPFingerprint.toErrorResult() + } ?: return PiPFingerprint.toErrorResult() + } ?: return PiPParentFingerprint.toErrorResult() return PatchResultSuccess() } - - private companion object { - const val REFERENCE_DESCRIPTOR = - "Landroid/app/Activity;->enterPictureInPictureMode(Landroid/app/PictureInPictureParams;)Z" - } } \ No newline at end of file