diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt index b2cf51d22..626c5c3e2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt @@ -43,4 +43,5 @@ object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( methodDef.implementation!!.instructions.any { ((it as? NarrowLiteralInstruction)?.narrowLiteral == 5) } - }) + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackAudioFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackAudioFingerprint.kt new file mode 100644 index 000000000..b373db941 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackAudioFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.AudioUnavailable +import app.revanced.util.bytecode.isWideLiteralExists +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +object MinimizedPlaybackAudioFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ + ), + customFingerprint = { methodDef, _ -> methodDef.isWideLiteralExists(AudioUnavailable) } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackFingerprint.kt new file mode 100644 index 000000000..d52c4e39a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +object MinimizedPlaybackFingerprint : MethodFingerprint( + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"), + opcodes = listOf( + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/PiPPlaybackFingerprint.kt similarity index 51% rename from src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/PiPPlaybackFingerprint.kt index 1358b0936..8cc90eebf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/PiPPlaybackFingerprint.kt @@ -2,14 +2,18 @@ package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.util.bytecode.isNarrowLiteralExists import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -object MinimizedPlaybackManagerFingerprint : MethodFingerprint( +object PiPPlaybackFingerprint : MethodFingerprint( returnType = "Z", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("L"), - opcodes = listOf(Opcode.AND_INT_LIT16), - customFingerprint = { methodDef, _ -> methodDef.isNarrowLiteralExists(64657230) } -) \ No newline at end of file + parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"), + opcodes = listOf( + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt index ca0caedac..1aa7ce67a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt @@ -6,18 +6,22 @@ import app.revanced.patcher.annotation.Name import app.revanced.patcher.data.BytecodeContext 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.patch.BytecodePatch import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint +import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackAudioFingerprint +import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackFingerprint import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint +import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.PiPPlaybackFingerprint import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.utils.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch import app.revanced.util.integrations.Constants.MISC_PATH +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.reference.MethodReference @@ -26,8 +30,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Description("Enables minimized and background playback.") @DependsOn( [ - PlayerTypeHookPatch::class, IntegrationsPatch::class, + PlayerTypeHookPatch::class, SharedResourceIdPatch::class ] ) @@ -35,64 +39,79 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference class MinimizedPlaybackPatch : BytecodePatch( listOf( KidsMinimizedPlaybackPolicyControllerFingerprint, - MinimizedPlaybackManagerFingerprint, - MinimizedPlaybackSettingsFingerprint + MinimizedPlaybackAudioFingerprint, + MinimizedPlaybackFingerprint, + MinimizedPlaybackSettingsFingerprint, + PiPPlaybackFingerprint ) ) { override fun execute(context: BytecodeContext) { - val methods = arrayOf( - KidsMinimizedPlaybackPolicyControllerFingerprint, - MinimizedPlaybackManagerFingerprint, - MinimizedPlaybackSettingsFingerprint - ).map { - it.result?.mutableMethod ?: throw it.exception + KidsMinimizedPlaybackPolicyControllerFingerprint.result?.let { + it.mutableMethod.apply { + addInstruction( + 0, + "return-void" + ) + } + } ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception + + arrayOf( + MinimizedPlaybackAudioFingerprint, + MinimizedPlaybackFingerprint + ).forEach { fingerprint -> + fingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = + getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "const/4 v$insertRegister, 0x1" + ) + } + } ?: throw fingerprint.exception } - methods[0].hookKidsMiniPlayer() - methods[1].hookMinimizedPlaybackManager() - methods[2].hookMinimizedPlaybackSettings(context) + MinimizedPlaybackSettingsFingerprint.result?.let { + it.mutableMethod.apply { + val booleanCalls = implementation!!.instructions.withIndex() + .filter { instruction -> + ((instruction.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" + } + val booleanIndex = booleanCalls.elementAt(1).index + val booleanMethod = + context.toMethodWalker(this) + .nextMethod(booleanIndex, true) + .getMethod() as MutableMethod + + booleanMethod.addInstructions( + 0, """ + const/4 v0, 0x1 + return v0 + """ + ) + } + } ?: throw MinimizedPlaybackSettingsFingerprint.exception + + PiPPlaybackFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {}, $INTEGRATIONS_METHOD_REFERENCE + move-result v$insertRegister + """ + ) + } + } ?: throw PiPPlaybackFingerprint.exception } private companion object { const val INTEGRATIONS_METHOD_REFERENCE = "$MISC_PATH/MinimizedPlaybackPatch;->isPlaybackNotShort()Z" - - fun MutableMethod.hookKidsMiniPlayer() { - addInstruction( - 0, - "return-void" - ) - } - - fun MutableMethod.hookMinimizedPlaybackManager() { - addInstructions( - 0, """ - invoke-static {}, $INTEGRATIONS_METHOD_REFERENCE - move-result v0 - return v0 - """ - ) - } - - fun MutableMethod.hookMinimizedPlaybackSettings( - context: BytecodeContext - ) { - val booleanCalls = implementation!!.instructions.withIndex() - .filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" } - - val booleanIndex = booleanCalls.elementAt(1).index - val booleanMethod = - context.toMethodWalker(this) - .nextMethod(booleanIndex, true) - .getMethod() as MutableMethod - - booleanMethod.addInstructions( - 0, """ - const/4 v0, 0x1 - return v0 - """ - ) - } } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/patch/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/patch/SharedResourceIdPatch.kt index 2c719a6c3..c35f134d8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/patch/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/patch/SharedResourceIdPatch.kt @@ -22,6 +22,7 @@ class SharedResourceIdPatch : ResourcePatch { var AdAttribution: Long = -1 var Appearance: Long = -1 var AppRelatedEndScreenResults: Long = -1 + var AudioUnavailable: Long = -1 var AutoNavPreviewStub: Long = -1 var AutoNavToggle: Long = -1 var BackgroundCategory: Long = -1 @@ -102,6 +103,7 @@ class SharedResourceIdPatch : ResourcePatch { AdAttribution = find(ID, "ad_attribution") Appearance = find(STRING, "app_theme_appearance_dark") AppRelatedEndScreenResults = find(LAYOUT, "app_related_endscreen_results") + AudioUnavailable = find(STRING, "audio_unavailable") AutoNavPreviewStub = find(ID, "autonav_preview_stub") AutoNavToggle = find(ID, "autonav_toggle") BackgroundCategory = find(STRING, "pref_background_and_offline_category")