From 33ea12228c2ae5dcadf3e7c7016d4bf6006d899a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 26 Mar 2024 00:32:59 +0100 Subject: [PATCH] fix(YouTube): Fix video playback by switching to ReVanced GmsCore vendor (#2907) The previous vendor did not update GmsCore, resulting in missing features required for playback, specifically PoToken, which was added to requests recently. Because the PoToken was missing, playback failed. --- api/revanced-patches.api | 1 + .../music/misc/gms/GmsCoreSupportPatch.kt | 10 ++--- .../misc/gms/BaseGmsCoreSupportPatch.kt | 42 ++++++++++++------- .../gms/BaseGmsCoreSupportResourcePatch.kt | 33 +++++++++------ .../misc/fix/playback/ClientSpoofPatch.kt | 3 +- .../misc/fix/playback/SpoofSignaturePatch.kt | 13 +----- .../youtube/misc/gms/GmsCoreSupportPatch.kt | 20 ++++----- .../misc/gms/GmsCoreSupportResourcePatch.kt | 9 ++-- 8 files changed, 71 insertions(+), 60 deletions(-) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index f82f86e4..80dc7446 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -636,6 +636,7 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V protected final fun getGmsCoreVendor ()Ljava/lang/String; + protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String; } public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch { diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt index 5bb8e2a4..65d90539 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt @@ -2,12 +2,12 @@ package app.revanced.patches.music.misc.gms import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME -import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption +import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption import app.revanced.patches.music.misc.gms.fingerprints.* -import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint import app.revanced.patches.music.misc.integrations.IntegrationsPatch -import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch +import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint +import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch @Suppress("unused") object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( @@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, PrimeMethodFingerprint, - ) + ), ) { - override val gmsCoreVendor by gmsCoreVendorOption + override val gmsCoreVendor by gmsCoreVendorGroupIdOption } diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt index 5c118db6..87e10ad8 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt @@ -53,15 +53,15 @@ abstract class BaseGmsCoreSupportPatch( ) : BytecodePatch( name = "GmsCore support", description = "Allows patched Google apps to run without root and under a different package name " + - "by using GmsCore instead of Google Play Services.", + "by using GmsCore instead of Google Play Services.", dependencies = setOf( ChangePackageNamePatch::class, gmsCoreSupportResourcePatch::class, - integrationsPatchDependency + integrationsPatchDependency, ) + dependencies, compatiblePackages = compatiblePackages, fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints, - requiresIntegrations = true + requiresIntegrations = true, ) { init { // Manually register all options of the resource patch so that they are visible in the patch API. @@ -77,7 +77,7 @@ abstract class BaseGmsCoreSupportPatch( val transformations = arrayOf( ::commonTransform, ::contentUrisTransform, - packageNameTransform(fromPackageName, packageName) + packageNameTransform(fromPackageName, packageName), ) context.transformStringReferences transform@{ string -> transformations.forEach { transform -> @@ -96,7 +96,7 @@ abstract class BaseGmsCoreSupportPatch( // Check the availability of GmsCore. mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction( 1, // Hack to not disturb other patches (such as the integrations patch). - "invoke-static {}, Lapp/revanced/integrations/youtube/patches/GmsCoreSupport;->checkAvailability()V" + "invoke-static {}, Lapp/revanced/integrations/youtube/patches/GmsCoreSupport;->checkAvailability()V", ) ?: throw mainActivityOnCreateFingerprint.exception // Change the vendor of GmsCore in ReVanced Integrations. @@ -130,8 +130,8 @@ abstract class BaseGmsCoreSupportPatch( BuilderInstruction21c( Opcode.CONST_STRING, instruction.registerA, - ImmutableStringReference(transformedString) - ) + ImmutableStringReference(transformedString), + ), ) } } @@ -145,7 +145,8 @@ abstract class BaseGmsCoreSupportPatch( "com.google.android.gms", in PERMISSIONS, in ACTIONS, - in AUTHORITIES -> referencedString.replace("com.google", gmsCoreVendor!!) + in AUTHORITIES, + -> referencedString.replace("com.google", gmsCoreVendor!!) // No vendor prefix for whatever reason... "subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds" @@ -161,7 +162,7 @@ abstract class BaseGmsCoreSupportPatch( if (str.startsWith(uriPrefix)) { return str.replace( uriPrefix, - "content://${authority.replace("com.google", gmsCoreVendor!!)}" + "content://${authority.replace("com.google", gmsCoreVendor!!)}", ) } } @@ -174,13 +175,13 @@ abstract class BaseGmsCoreSupportPatch( } return null - } private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string -> when (string) { "$fromPackageName.SuggestionsProvider", - "$fromPackageName.fileprovider" -> string.replace(fromPackageName, toPackageName) + "$fromPackageName.fileprovider", + -> string.replace(fromPackageName, toPackageName) else -> null } @@ -273,6 +274,9 @@ abstract class BaseGmsCoreSupportPatch( // fido "com.google.android.gms.fido.fido2.privileged.START", + // gass + "com.google.android.gms.gass.START", + // games "com.google.android.gms.games.service.START", "com.google.android.gms.games.PLAY_GAMES_UPGRADE", @@ -292,8 +296,18 @@ abstract class BaseGmsCoreSupportPatch( // misc "com.google.android.gms.gmscompliance.service.START", "com.google.android.gms.oss.licenses.service.START", + "com.google.android.gms.tapandpay.service.BIND", + "com.google.android.gms.measurement.START", + "com.google.android.gms.languageprofile.service.START", + "com.google.android.gms.clearcut.service.START", + "com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE", + + // potoken + "com.google.android.gms.potokens.service.START", + + // droidguard/ safetynet + "com.google.android.gms.droidguard.service.START", "com.google.android.gms.safetynet.service.START", - "com.google.android.gms.tapandpay.service.BIND" ) /** @@ -314,9 +328,9 @@ abstract class BaseGmsCoreSupportPatch( "com.google.android.gms.fonts", // phenotype - "com.google.android.gms.phenotype" + "com.google.android.gms.phenotype", ) } // endregion -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt index e42f3360..eef039f7 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt @@ -24,21 +24,23 @@ abstract class BaseGmsCoreSupportResourcePatch( private val spoofedPackageSignature: String, dependencies: Set = setOf(), ) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) { - internal val gmsCoreVendorOption = + internal val gmsCoreVendorGroupIdOption = stringPatchOption( - key = "gmsCoreVendor", - default = "com.mgoogle", + key = "gmsCoreVendorGroupId", + default = "app.revanced", values = mapOf( - "Vanced" to "com.mgoogle", "ReVanced" to "app.revanced", ), - title = "GmsCore Vendor", - description = "The group id of the GmsCore vendor.", + title = "GmsCore vendor group ID", + description = "The vendor's group ID for GmsCore.", required = true, - ) { it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) } + ) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) } - protected val gmsCoreVendor by gmsCoreVendorOption + protected val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption + + @Deprecated("Use gmsCoreVendorGroupId instead.", ReplaceWith("gmsCoreVendorGroupId")) + protected val gmsCoreVendor by gmsCoreVendorGroupIdOption override fun execute(context: ResourceContext) { AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class) @@ -70,12 +72,12 @@ abstract class BaseGmsCoreSupportResourcePatch( // Spoof package name and signature. applicationNode.adoptChild("meta-data") { - setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_NAME") + setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_NAME") setAttribute("android:value", fromPackageName) } applicationNode.adoptChild("meta-data") { - setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_SIGNATURE") + setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_SIGNATURE") setAttribute("android:value", spoofedPackageSignature) } @@ -83,7 +85,7 @@ abstract class BaseGmsCoreSupportResourcePatch( applicationNode.adoptChild("meta-data") { // TODO: The name of this metadata should be dynamic. setAttribute("android:name", "app.revanced.MICROG_PACKAGE_NAME") - setAttribute("android:value", "$gmsCoreVendor.android.gms") + setAttribute("android:value", "$gmsCoreVendorGroupId.android.gms") } } } @@ -110,11 +112,16 @@ abstract class BaseGmsCoreSupportResourcePatch( "$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", ).replace( "com.google.android.c2dm", - "$gmsCoreVendor.android.c2dm", + "$gmsCoreVendorGroupId.android.c2dm", ).replace( "", - "", + "", ), ) } + + private companion object { + private const val VANCED_VENDOR = "com.mgoogle" + private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$" + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt index 57572996..aeb1788d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt @@ -18,8 +18,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Client spoof", - description = "Adds options to spoof the client to allow video playback.", - dependencies = [SpoofSignaturePatch::class], + description = "Spoofs the client to allow video playback.", compatiblePackages = [ CompatiblePackage("com.google.android.youtube"), ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt index 5a00c791..4e9a7833 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt @@ -13,21 +13,11 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.fix.playback.fingerprints.* -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ParamsMapPutFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplGeneralFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplLiveStreamFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplRecommendedLevelFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ScrubbedPreviewLayoutFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderRecommendedLevelFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderSpecFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererSpecFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailParentFingerprint import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch -import app.revanced.util.* +import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @@ -43,6 +33,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction AddResourcesPatch::class, ], ) +@Deprecated("This patch will be removed in the future.") object SpoofSignaturePatch : BytecodePatch( setOf( PlayerResponseModelImplGeneralFingerprint, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt index 21899ec2..ff290235 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt @@ -6,12 +6,11 @@ import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME -import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption +import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption import app.revanced.patches.youtube.misc.gms.fingerprints.* import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint - @Suppress("unused") object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( fromPackageName = YOUTUBE_PACKAGE_NAME, @@ -22,18 +21,19 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint + CastContextFetchFingerprint, ), mainActivityOnCreateFingerprint = HomeActivityFingerprint, integrationsPatchDependency = IntegrationsPatch::class, dependencies = setOf( HideCastButtonPatch::class, - ClientSpoofPatch::class + ClientSpoofPatch::class, ), gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, compatiblePackages = setOf( CompatiblePackage( - "com.google.android.youtube", setOf( + "com.google.android.youtube", + setOf( "18.48.39", "18.49.37", "19.01.34", @@ -44,9 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( "19.06.39", "19.07.40", "19.08.36", - "19.09.37" - ) - ) + "19.09.37", + ), + ), ), fingerprints = setOf( ServiceCheckFingerprint, @@ -55,7 +55,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, PrimeMethodFingerprint, - ) + ), ) { - override val gmsCoreVendor by gmsCoreVendorOption + override val gmsCoreVendor by gmsCoreVendorGroupIdOption } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt index 151e1b6c..730d921a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt @@ -8,12 +8,11 @@ import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_ import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.settings.SettingsPatch - object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( fromPackageName = YOUTUBE_PACKAGE_NAME, toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME, spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600", - dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class) + dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class), ) { override fun execute(context: ResourceContext) { AddResourcesPatch(this::class) @@ -22,9 +21,9 @@ object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( IntentPreference( "microg_settings", intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") { - "$gmsCoreVendor.android.gms" - } - ) + "$gmsCoreVendorGroupId.android.gms" + }, + ), ) super.execute(context)