feat: merge the Custom package name patch into the GmsCore support patch and add patch options GmsCoreVendorGroupId, CheckGmsCore, PackageNameYouTube, PackageNameYouTubeMusic

This commit is contained in:
inotia00 2024-07-17 13:40:03 +09:00
parent 3947804ace
commit 2d670c2d36
9 changed files with 168 additions and 115 deletions

View File

@ -4,20 +4,19 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.utils.fix.fileprovider.fingerprints.FileProviderResolverFingerprint
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patches.music.utils.gms.GmsCoreSupportResourcePatch
import app.revanced.util.resultOrThrow
import app.revanced.util.valueOrThrow
@Patch(dependencies = [PackageNamePatch::class])
object FileProviderPatch : BytecodePatch(
setOf(FileProviderResolverFingerprint)
) {
override fun execute(context: BytecodeContext) {
val youtubePackageName = PackageNamePatch.packageNameYouTube
val musicPackageName = PackageNamePatch.packageNameYouTubeMusic
val youtubePackageName = GmsCoreSupportResourcePatch.PackageNameYouTube.valueOrThrow()
val musicPackageName = GmsCoreSupportResourcePatch.PackageNameYouTubeMusic.valueOrThrow()
/**
* For some reason, if the app gets "android.support.FILE_PROVIDER_PATHS",

View File

@ -6,17 +6,15 @@ import app.revanced.patches.music.utils.fix.fileprovider.FileProviderPatch
import app.revanced.patches.music.utils.integrations.IntegrationsPatch
import app.revanced.patches.music.utils.mainactivity.fingerprints.MainActivityFingerprint
import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patches.shared.packagename.PackageNamePatch.ORIGINAL_PACKAGE_NAME_YOUTUBE
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch.Companion.ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC
@Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC,
mainActivityOnCreateFingerprint = MainActivityFingerprint,
integrationsPatchDependency = IntegrationsPatch::class,
dependencies = setOf(
SpoofUserAgentPatch::class,
PackageNamePatch::class,
FileProviderPatch::class
),
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,

View File

@ -6,26 +6,24 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.addMicroGPreferen
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePackageName
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patches.shared.packagename.PackageNamePatch.ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC
import app.revanced.util.valueOrThrow
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC,
spoofedPackageSignature = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875",
dependencies = setOf(PackageNamePatch::class, SettingsPatch::class),
dependencies = setOf(SettingsPatch::class),
) {
private const val GMS_CORE_PACKAGE_NAME = "app.revanced.android.gms"
private const val GMS_CORE_SETTINGS_ACTIVITY = "org.microg.gms.ui.SettingsActivity"
override fun execute(context: ResourceContext) {
super.execute(context)
context.updatePackageName(PackageNamePatch.packageNameYouTubeMusic)
context.updatePackageName(PackageNameYouTubeMusic.valueOrThrow())
context.addMicroGPreference(
CategoryType.MISC.value,
"gms_core_settings",
GMS_CORE_PACKAGE_NAME,
GmsCoreVendorGroupId.valueOrThrow(),
GMS_CORE_SETTINGS_ACTIVITY
)
}

View File

@ -8,9 +8,12 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch.Constants.ACTIONS
import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch.Constants.AUTHORITIES
import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch.Constants.PERMISSIONS
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch.Companion.ORIGINAL_PACKAGE_NAME_YOUTUBE
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch.Companion.ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC
import app.revanced.patches.shared.gms.fingerprints.CastContextFetchFingerprint
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleFingerprint
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleV2Fingerprint
@ -21,7 +24,6 @@ import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint
import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint
import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.resultOrThrow
@ -46,6 +48,7 @@ import com.android.tools.smali.dexlib2.util.MethodUtil
* @param dependencies Additional dependencies of this patch.
* @param compatiblePackages The compatible packages of this patch.
*/
@Suppress("SameParameterValue")
abstract class BaseGmsCoreSupportPatch(
private val fromPackageName: String,
private val mainActivityOnCreateFingerprint: MethodFingerprint,
@ -58,7 +61,6 @@ abstract class BaseGmsCoreSupportPatch(
description = "Allows patched Google apps to run without root and under a different package name " +
"by using GmsCore instead of Google Play Services.",
dependencies = setOf(
PackageNamePatch::class,
gmsCoreSupportResourcePatch::class,
integrationsPatchDependency,
) + dependencies,
@ -82,14 +84,53 @@ abstract class BaseGmsCoreSupportPatch(
requiresIntegrations = true,
) {
private companion object {
const val GMS_CORE_VENDOR_GROUP_ID = "app.revanced"
const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$PATCHES_PATH/GmsCoreSupport;"
var gmsCoreVendor = "app.revanced"
var checkGmsCore = true
var packageNameYouTube = "com.google.android.youtube"
var packageNameYouTubeMusic = "com.google.android.apps.youtube.music"
}
init {
// Manually register all options of the resource patch so that they are visible in the patch API.
gmsCoreSupportResourcePatch.options.values.forEach(options::register)
}
private fun getBooleanPatchOption(optionKey: String): Boolean {
this.options.values.forEach { options ->
if (options.key == optionKey && options.value is Boolean)
return options.value as Boolean
}
throw PatchException("Patch option not found: $optionKey")
}
private fun getStringPatchOption(optionKey: String): String {
this.options.values.forEach { options ->
if (options.key == optionKey)
return options.value.toString()
}
throw PatchException("Patch option not found: $optionKey")
}
private fun getPackageName(originalPackageName: String): String {
if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE) {
return packageNameYouTube
} else if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC) {
return packageNameYouTubeMusic
}
throw PatchException("Unknown package name!")
}
override fun execute(context: BytecodeContext) {
val packageName = PackageNamePatch.getPackageName(fromPackageName)
gmsCoreVendor = getStringPatchOption("GmsCoreVendorGroupId")
checkGmsCore = getBooleanPatchOption("CheckGmsCore")
packageNameYouTube = getStringPatchOption("PackageNameYouTube")
packageNameYouTubeMusic = getStringPatchOption("PackageNameYouTubeMusic")
val packageName = getPackageName(fromPackageName)
// Transform all strings using all provided transforms, first match wins.
val transformations = arrayOf(
@ -119,17 +160,19 @@ abstract class BaseGmsCoreSupportPatch(
).returnEarly()
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
"invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->" +
"checkGmsCore(Landroid/app/Activity;)V",
)
if (checkGmsCore) {
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
"invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->" +
"checkGmsCore(Landroid/app/Activity;)V",
)
}
// Change the vendor of GmsCore in ReVanced Integrations.
GmsCoreSupportFingerprint
.resultOrThrow()
.mutableMethod
.replaceInstruction(0, "const-string v0, \"$GMS_CORE_VENDOR_GROUP_ID\"")
.replaceInstruction(0, "const-string v0, \"$gmsCoreVendor\"")
// Spoof signature.
CertificateFingerprint.result?.mutableClass?.methods?.forEach { mutableMethod ->
@ -197,10 +240,10 @@ abstract class BaseGmsCoreSupportPatch(
in PERMISSIONS,
in ACTIONS,
in AUTHORITIES,
-> referencedString.replace("com.google", GMS_CORE_VENDOR_GROUP_ID)
-> referencedString.replace("com.google", gmsCoreVendor)
// No vendor prefix for whatever reason...
"subscribedfeeds" -> "$GMS_CORE_VENDOR_GROUP_ID.subscribedfeeds"
"subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds"
else -> null
}
@ -213,7 +256,7 @@ abstract class BaseGmsCoreSupportPatch(
if (str.startsWith(uriPrefix)) {
return str.replace(
uriPrefix,
"content://${authority.replace("com.google", GMS_CORE_VENDOR_GROUP_ID)}",
"content://${authority.replace("com.google", gmsCoreVendor)}",
)
}
}
@ -223,7 +266,7 @@ abstract class BaseGmsCoreSupportPatch(
if (str.startsWith(subFeedsUriPrefix)) {
return str.replace(
subFeedsUriPrefix,
"content://$GMS_CORE_VENDOR_GROUP_ID.subscribedfeeds"
"content://$gmsCoreVendor.subscribedfeeds"
)
}
}

View File

@ -2,8 +2,11 @@ package app.revanced.patches.shared.gms
import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.util.valueOrThrow
import org.w3c.dom.Element
import org.w3c.dom.Node
@ -15,15 +18,59 @@ import org.w3c.dom.Node
* @param spoofedPackageSignature The signature of the package to spoof to.
* @param dependencies Additional dependencies of this patch.
*/
@Suppress("DEPRECATION")
@Suppress("DEPRECATION", "PrivatePropertyName", "PropertyName", "unused")
abstract class BaseGmsCoreSupportResourcePatch(
private val fromPackageName: String,
private val spoofedPackageSignature: String,
dependencies: Set<PatchClass> = setOf(),
) : ResourcePatch(
dependencies = setOf(PackageNamePatch::class) + dependencies
dependencies = dependencies
) {
private val gmsCoreVendorGroupId = "app.revanced"
internal val GmsCoreVendorGroupId =
stringPatchOption(
key = "GmsCoreVendorGroupId",
default = DEFAULT_GMS_CORE_VENDOR_GROUP_ID,
values =
mapOf(
"ReVanced" to DEFAULT_GMS_CORE_VENDOR_GROUP_ID,
),
title = "GmsCore vendor group ID",
description = "The vendor's group ID for GmsCore.",
required = true,
) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) }
private val CheckGmsCore by booleanPatchOption(
key = "CheckGmsCore",
default = true,
title = "Check GmsCore",
description = "The vendor's group ID for GmsCore.",
required = true,
)
internal val PackageNameYouTube = stringPatchOption(
key = "PackageNameYouTube",
default = DEFAULT_PACKAGE_NAME_YOUTUBE,
values = mapOf(
"Clone" to CLONE_PACKAGE_NAME_YOUTUBE,
"Default" to DEFAULT_PACKAGE_NAME_YOUTUBE
),
title = "Package name of YouTube",
description = "The name of the package to use in GmsCore support.",
required = true
) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) && it != ORIGINAL_PACKAGE_NAME_YOUTUBE }
internal val PackageNameYouTubeMusic = stringPatchOption(
key = "PackageNameYouTubeMusic",
default = DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC,
values = mapOf(
"Clone" to CLONE_PACKAGE_NAME_YOUTUBE_MUSIC,
"Default" to DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC
),
title = "Package name of YouTube Music",
description = "The name of the package to use in GmsCore support.",
required = true
) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) && it != ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC }
protected val gmsCoreVendorGroupId by GmsCoreVendorGroupId
override fun execute(context: ResourceContext) {
context.patchManifest()
@ -81,7 +128,7 @@ abstract class BaseGmsCoreSupportResourcePatch(
* Patch the manifest to support GmsCore.
*/
private fun ResourceContext.patchManifest() {
val packageName = PackageNamePatch.getPackageName(fromPackageName)
val packageName = getPackageName(fromPackageName)
val manifest = this["AndroidManifest.xml"].readText()
this["AndroidManifest.xml"].writeText(
@ -113,4 +160,27 @@ abstract class BaseGmsCoreSupportResourcePatch(
}
}
}
private fun getPackageName(originalPackageName: String): String {
if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE) {
return PackageNameYouTube.valueOrThrow()
} else if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC) {
return PackageNameYouTubeMusic.valueOrThrow()
}
throw PatchException("Unknown package name!")
}
companion object {
internal const val DEFAULT_GMS_CORE_VENDOR_GROUP_ID = "app.revanced"
private const val CLONE_PACKAGE_NAME_YOUTUBE = "com.rvx.android.youtube"
private const val DEFAULT_PACKAGE_NAME_YOUTUBE = "app.rvx.android.youtube"
internal const val ORIGINAL_PACKAGE_NAME_YOUTUBE = "com.google.android.youtube"
private const val CLONE_PACKAGE_NAME_YOUTUBE_MUSIC = "com.rvx.android.apps.youtube.music"
private const val DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC = "app.rvx.android.apps.youtube.music"
internal const val ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC = "com.google.android.apps.youtube.music"
private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
}
}

View File

@ -1,72 +0,0 @@
package app.revanced.patches.shared.packagename
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
@Patch(
name = "Custom package name",
description = "Changes the package name for the non-root build of YouTube and YouTube Music to the name specified in options.json.",
compatiblePackages = [
CompatiblePackage("com.google.android.youtube"),
CompatiblePackage("com.google.android.apps.youtube.music")
]
)
@Suppress("unused")
object PackageNamePatch : ResourcePatch() {
private const val CLONE_PACKAGE_NAME_YOUTUBE = "com.rvx.android.youtube"
private const val DEFAULT_PACKAGE_NAME_YOUTUBE = "app.rvx.android.youtube"
internal const val ORIGINAL_PACKAGE_NAME_YOUTUBE = "com.google.android.youtube"
private const val CLONE_PACKAGE_NAME_YOUTUBE_MUSIC = "com.rvx.android.apps.youtube.music"
private const val DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC = "app.rvx.android.apps.youtube.music"
internal const val ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC = "com.google.android.apps.youtube.music"
internal var packageNameYouTube = DEFAULT_PACKAGE_NAME_YOUTUBE
internal var packageNameYouTubeMusic = DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC
private val PackageNameYouTube by stringPatchOption(
key = "PackageNameYouTube",
default = DEFAULT_PACKAGE_NAME_YOUTUBE,
values = mapOf(
"Clone" to CLONE_PACKAGE_NAME_YOUTUBE,
"Default" to DEFAULT_PACKAGE_NAME_YOUTUBE
),
title = "Package name of YouTube",
description = "The name of the package to use in GmsCore support.",
required = true
)
private val PackageNameYouTubeMusic by stringPatchOption(
key = "PackageNameYouTubeMusic",
default = DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC,
values = mapOf(
"Clone" to CLONE_PACKAGE_NAME_YOUTUBE_MUSIC,
"Default" to DEFAULT_PACKAGE_NAME_YOUTUBE_MUSIC
),
title = "Package name of YouTube Music",
description = "The name of the package to use in GmsCore support.",
required = true
)
override fun execute(context: ResourceContext) {
if (PackageNameYouTube != null && PackageNameYouTube!! != ORIGINAL_PACKAGE_NAME_YOUTUBE) {
packageNameYouTube = PackageNameYouTube!!
}
if (PackageNameYouTubeMusic != null && PackageNameYouTubeMusic!! != ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC) {
packageNameYouTubeMusic = PackageNameYouTubeMusic!!
}
}
fun getPackageName(originalPackageName: String): String {
if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE) {
return packageNameYouTube
} else if (originalPackageName == ORIGINAL_PACKAGE_NAME_YOUTUBE_MUSIC) {
return packageNameYouTubeMusic
}
throw PatchException("Unknown package name!")
}
}

View File

@ -1,8 +1,7 @@
package app.revanced.patches.youtube.utils.gms
import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patches.shared.packagename.PackageNamePatch.ORIGINAL_PACKAGE_NAME_YOUTUBE
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch.Companion.ORIGINAL_PACKAGE_NAME_YOUTUBE
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.fix.client.SpoofClientPatch
import app.revanced.patches.youtube.utils.fix.client.SpoofUserAgentPatch
@ -18,7 +17,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
dependencies = setOf(
SpoofClientPatch::class,
SpoofUserAgentPatch::class,
PackageNamePatch::class,
SettingsPatch::class
),
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,

View File

@ -2,15 +2,15 @@ package app.revanced.patches.youtube.utils.gms
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch
import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.patches.shared.packagename.PackageNamePatch.ORIGINAL_PACKAGE_NAME_YOUTUBE
import app.revanced.patches.youtube.utils.settings.ResourceUtils.updateGmsCorePackageName
import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePackageName
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.valueOrThrow
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
dependencies = setOf(PackageNamePatch::class, SettingsPatch::class),
dependencies = setOf(SettingsPatch::class),
) {
override fun execute(context: ResourceContext) {
super.execute(context)
@ -27,7 +27,11 @@ object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
context.updatePackageName(
ORIGINAL_PACKAGE_NAME_YOUTUBE,
PackageNamePatch.packageNameYouTube
PackageNameYouTube.valueOrThrow()
)
context.updateGmsCorePackageName(
DEFAULT_GMS_CORE_VENDOR_GROUP_ID,
GmsCoreVendorGroupId.valueOrThrow()
)
}
}

View File

@ -23,7 +23,22 @@ object ResourceUtils {
) {
youtubePackageName = toPackageName
val prefs = this["res/xml/settings_fragment.xml"]
val prefs = this[YOUTUBE_SETTINGS_PATH]
prefs.writeText(
prefs.readText()
.replace(
"android:targetPackage=\"$fromPackageName",
"android:targetPackage=\"$toPackageName"
)
)
}
fun ResourceContext.updateGmsCorePackageName(
fromPackageName: String,
toPackageName: String
) {
val prefs = this[TARGET_PREFERENCE_PATH]
prefs.writeText(
prefs.readText()