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.
This commit is contained in:
oSumAtrIX 2024-03-26 00:32:59 +01:00 committed by GitHub
parent 6bd8d01856
commit 33ea12228c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 71 additions and 60 deletions

View file

@ -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 synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
protected final fun getGmsCoreVendor ()Ljava/lang/String; 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 { public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {

View file

@ -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.MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.Constants.REVANCED_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.gms.fingerprints.*
import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint
import app.revanced.patches.music.misc.integrations.IntegrationsPatch 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.fingerprints.CastContextFetchFingerprint
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
@Suppress("unused") @Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint, CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint, CastContextFetchFingerprint,
PrimeMethodFingerprint, PrimeMethodFingerprint,
) ),
) { ) {
override val gmsCoreVendor by gmsCoreVendorOption override val gmsCoreVendor by gmsCoreVendorGroupIdOption
} }

View file

@ -53,15 +53,15 @@ abstract class BaseGmsCoreSupportPatch(
) : BytecodePatch( ) : BytecodePatch(
name = "GmsCore support", name = "GmsCore support",
description = "Allows patched Google apps to run without root and under a different package name " + 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( dependencies = setOf(
ChangePackageNamePatch::class, ChangePackageNamePatch::class,
gmsCoreSupportResourcePatch::class, gmsCoreSupportResourcePatch::class,
integrationsPatchDependency integrationsPatchDependency,
) + dependencies, ) + dependencies,
compatiblePackages = compatiblePackages, compatiblePackages = compatiblePackages,
fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints, fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints,
requiresIntegrations = true requiresIntegrations = true,
) { ) {
init { init {
// Manually register all options of the resource patch so that they are visible in the patch API. // 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( val transformations = arrayOf(
::commonTransform, ::commonTransform,
::contentUrisTransform, ::contentUrisTransform,
packageNameTransform(fromPackageName, packageName) packageNameTransform(fromPackageName, packageName),
) )
context.transformStringReferences transform@{ string -> context.transformStringReferences transform@{ string ->
transformations.forEach { transform -> transformations.forEach { transform ->
@ -96,7 +96,7 @@ abstract class BaseGmsCoreSupportPatch(
// Check the availability of GmsCore. // Check the availability of GmsCore.
mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction( mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction(
1, // Hack to not disturb other patches (such as the integrations patch). 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 ) ?: throw mainActivityOnCreateFingerprint.exception
// Change the vendor of GmsCore in ReVanced Integrations. // Change the vendor of GmsCore in ReVanced Integrations.
@ -130,8 +130,8 @@ abstract class BaseGmsCoreSupportPatch(
BuilderInstruction21c( BuilderInstruction21c(
Opcode.CONST_STRING, Opcode.CONST_STRING,
instruction.registerA, instruction.registerA,
ImmutableStringReference(transformedString) ImmutableStringReference(transformedString),
) ),
) )
} }
} }
@ -145,7 +145,8 @@ abstract class BaseGmsCoreSupportPatch(
"com.google.android.gms", "com.google.android.gms",
in PERMISSIONS, in PERMISSIONS,
in ACTIONS, in ACTIONS,
in AUTHORITIES -> referencedString.replace("com.google", gmsCoreVendor!!) in AUTHORITIES,
-> referencedString.replace("com.google", gmsCoreVendor!!)
// No vendor prefix for whatever reason... // No vendor prefix for whatever reason...
"subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds" "subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds"
@ -161,7 +162,7 @@ abstract class BaseGmsCoreSupportPatch(
if (str.startsWith(uriPrefix)) { if (str.startsWith(uriPrefix)) {
return str.replace( return str.replace(
uriPrefix, uriPrefix,
"content://${authority.replace("com.google", gmsCoreVendor!!)}" "content://${authority.replace("com.google", gmsCoreVendor!!)}",
) )
} }
} }
@ -174,13 +175,13 @@ abstract class BaseGmsCoreSupportPatch(
} }
return null return null
} }
private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string -> private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string ->
when (string) { when (string) {
"$fromPackageName.SuggestionsProvider", "$fromPackageName.SuggestionsProvider",
"$fromPackageName.fileprovider" -> string.replace(fromPackageName, toPackageName) "$fromPackageName.fileprovider",
-> string.replace(fromPackageName, toPackageName)
else -> null else -> null
} }
@ -273,6 +274,9 @@ abstract class BaseGmsCoreSupportPatch(
// fido // fido
"com.google.android.gms.fido.fido2.privileged.START", "com.google.android.gms.fido.fido2.privileged.START",
// gass
"com.google.android.gms.gass.START",
// games // games
"com.google.android.gms.games.service.START", "com.google.android.gms.games.service.START",
"com.google.android.gms.games.PLAY_GAMES_UPGRADE", "com.google.android.gms.games.PLAY_GAMES_UPGRADE",
@ -292,8 +296,18 @@ abstract class BaseGmsCoreSupportPatch(
// misc // misc
"com.google.android.gms.gmscompliance.service.START", "com.google.android.gms.gmscompliance.service.START",
"com.google.android.gms.oss.licenses.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.safetynet.service.START",
"com.google.android.gms.tapandpay.service.BIND"
) )
/** /**
@ -314,9 +328,9 @@ abstract class BaseGmsCoreSupportPatch(
"com.google.android.gms.fonts", "com.google.android.gms.fonts",
// phenotype // phenotype
"com.google.android.gms.phenotype" "com.google.android.gms.phenotype",
) )
} }
// endregion // endregion
} }

View file

@ -24,21 +24,23 @@ abstract class BaseGmsCoreSupportResourcePatch(
private val spoofedPackageSignature: String, private val spoofedPackageSignature: String,
dependencies: Set<PatchClass> = setOf(), dependencies: Set<PatchClass> = setOf(),
) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) { ) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) {
internal val gmsCoreVendorOption = internal val gmsCoreVendorGroupIdOption =
stringPatchOption( stringPatchOption(
key = "gmsCoreVendor", key = "gmsCoreVendorGroupId",
default = "com.mgoogle", default = "app.revanced",
values = values =
mapOf( mapOf(
"Vanced" to "com.mgoogle",
"ReVanced" to "app.revanced", "ReVanced" to "app.revanced",
), ),
title = "GmsCore Vendor", title = "GmsCore vendor group ID",
description = "The group id of the GmsCore vendor.", description = "The vendor's group ID for GmsCore.",
required = true, 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) { override fun execute(context: ResourceContext) {
AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class) AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class)
@ -70,12 +72,12 @@ abstract class BaseGmsCoreSupportResourcePatch(
// Spoof package name and signature. // Spoof package name and signature.
applicationNode.adoptChild("meta-data") { 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) setAttribute("android:value", fromPackageName)
} }
applicationNode.adoptChild("meta-data") { 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) setAttribute("android:value", spoofedPackageSignature)
} }
@ -83,7 +85,7 @@ abstract class BaseGmsCoreSupportResourcePatch(
applicationNode.adoptChild("meta-data") { applicationNode.adoptChild("meta-data") {
// TODO: The name of this metadata should be dynamic. // TODO: The name of this metadata should be dynamic.
setAttribute("android:name", "app.revanced.MICROG_PACKAGE_NAME") 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", "$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION",
).replace( ).replace(
"com.google.android.c2dm", "com.google.android.c2dm",
"$gmsCoreVendor.android.c2dm", "$gmsCoreVendorGroupId.android.c2dm",
).replace( ).replace(
"</queries>", "</queries>",
"<package android:name=\"$gmsCoreVendor.android.gms\"/></queries>", "<package android:name=\"$gmsCoreVendorGroupId.android.gms\"/></queries>",
), ),
) )
} }
private companion object {
private const val VANCED_VENDOR = "com.mgoogle"
private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
}
} }

View file

@ -18,8 +18,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
name = "Client spoof", name = "Client spoof",
description = "Adds options to spoof the client to allow video playback.", description = "Spoofs the client to allow video playback.",
dependencies = [SpoofSignaturePatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.google.android.youtube"), CompatiblePackage("com.google.android.youtube"),
], ],

View file

@ -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.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference 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.*
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.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.instruction.ReferenceInstruction
@ -43,6 +33,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
AddResourcesPatch::class, AddResourcesPatch::class,
], ],
) )
@Deprecated("This patch will be removed in the future.")
object SpoofSignaturePatch : BytecodePatch( object SpoofSignaturePatch : BytecodePatch(
setOf( setOf(
PlayerResponseModelImplGeneralFingerprint, PlayerResponseModelImplGeneralFingerprint,

View file

@ -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.fix.playback.ClientSpoofPatch
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME 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.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.gms.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint
@Suppress("unused") @Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
fromPackageName = YOUTUBE_PACKAGE_NAME, fromPackageName = YOUTUBE_PACKAGE_NAME,
@ -22,18 +21,19 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
GooglePlayUtilityFingerprint, GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint, CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint, CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint CastContextFetchFingerprint,
), ),
mainActivityOnCreateFingerprint = HomeActivityFingerprint, mainActivityOnCreateFingerprint = HomeActivityFingerprint,
integrationsPatchDependency = IntegrationsPatch::class, integrationsPatchDependency = IntegrationsPatch::class,
dependencies = setOf( dependencies = setOf(
HideCastButtonPatch::class, HideCastButtonPatch::class,
ClientSpoofPatch::class ClientSpoofPatch::class,
), ),
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
compatiblePackages = setOf( compatiblePackages = setOf(
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", setOf( "com.google.android.youtube",
setOf(
"18.48.39", "18.48.39",
"18.49.37", "18.49.37",
"19.01.34", "19.01.34",
@ -44,9 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.37",
) ),
) ),
), ),
fingerprints = setOf( fingerprints = setOf(
ServiceCheckFingerprint, ServiceCheckFingerprint,
@ -55,7 +55,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint, CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint, CastContextFetchFingerprint,
PrimeMethodFingerprint, PrimeMethodFingerprint,
) ),
) { ) {
override val gmsCoreVendor by gmsCoreVendorOption override val gmsCoreVendor by gmsCoreVendorGroupIdOption
} }

View file

@ -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.gms.Constants.YOUTUBE_PACKAGE_NAME
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = YOUTUBE_PACKAGE_NAME, fromPackageName = YOUTUBE_PACKAGE_NAME,
toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME, toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME,
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600", spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class) dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class),
) { ) {
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
@ -22,9 +21,9 @@ object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
IntentPreference( IntentPreference(
"microg_settings", "microg_settings",
intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") { intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") {
"$gmsCoreVendor.android.gms" "$gmsCoreVendorGroupId.android.gms"
} },
) ),
) )
super.execute(context) super.execute(context)