feat(YouTube - Downloads): Use external downloader when selecting 'Download' in home feed flyout menu (#2881)

This commit is contained in:
LisoUseInAIKyrios 2024-03-15 16:33:02 +04:00 committed by GitHub
parent 645d2883d9
commit 10afc8cc71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 16 additions and 78 deletions

View file

@ -6,9 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverFingerprint
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverParentFingerprint
import app.revanced.patches.youtube.interaction.downloads.fingerprints.LegacyDownloadCommandResolverFingerprint
import app.revanced.patches.youtube.interaction.downloads.fingerprints.OfflineVideoEndpointFingerprint
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch
@ -45,8 +43,7 @@ import app.revanced.util.resultOrThrow
@Suppress("unused")
object DownloadsPatch : BytecodePatch(
setOf(
DownloadActionCommandResolverParentFingerprint,
LegacyDownloadCommandResolverFingerprint,
OfflineVideoEndpointFingerprint,
MainActivityFingerprint
)
) {
@ -65,36 +62,16 @@ object DownloadsPatch : BytecodePatch(
)
}
val commonInstructions = """
move-result v0
if-eqz v0, :show_native_downloader
return-void
:show_native_downloader
nop
"""
DownloadActionCommandResolverFingerprint.resolve(context,
DownloadActionCommandResolverParentFingerprint.resultOrThrow().classDef)
DownloadActionCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
OfflineVideoEndpointFingerprint.resultOrThrow().mutableMethod.apply {
addInstructionsWithLabels(
0,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick()Z
$commonInstructions
"""
)
}
// Legacy fingerprint is used for old spoofed versions,
// or if download playlist is pressed on any version.
// Downloading playlists is not yet supported,
// as the code this hooks does not easily expost the playlist id.
LegacyDownloadCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
addInstructionsWithLabels(
0,
"""
invoke-static/range {p1 .. p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadPlaylistLegacyOnClick(Ljava/lang/String;)Z
$commonInstructions
invoke-static/range {p3 .. p3}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Ljava/lang/String;)Z
move-result v0
if-eqz v0, :show_native_downloader
return-void
:show_native_downloader
nop
"""
)
}

View file

@ -1,17 +0,0 @@
package app.revanced.patches.youtube.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object DownloadActionCommandResolverParentFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L", "L"),
strings = listOf(
// Strings are not unique and found in other methods.
"com.google.android.libraries.youtube.logging.interaction_logger",
"Unknown command"
),
literalSupplier = { 16 }
)

View file

@ -1,24 +0,0 @@
package app.revanced.patches.youtube.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* For spoofing to older versions. Also called if download playlist is pressed for any version.
*/
internal object LegacyDownloadCommandResolverFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;", "L", "L"),
strings = listOf(""),
opcodes = listOf(
Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
)
)

View file

@ -4,11 +4,13 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
/**
* Resolves to the class found in [DownloadActionCommandResolverParentFingerprint].
*/
internal object DownloadActionCommandResolverFingerprint : MethodFingerprint(
internal object OfflineVideoEndpointFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L", "Ljava/util/Map;")
parameters = listOf(
"Ljava/util/Map;",
"L",
"Ljava/lang/String", // VideoId
"L"),
strings = listOf("Object is not an offlineable video: ")
)