From c0bef255909ca884838675ca6f7ac5b0e2e21730 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Mar 2024 19:52:22 +0100 Subject: [PATCH] feat(YouTube - GmsCore): Require ignoring battery optimizations (#2952) --- .../music/misc/gms/GmsCoreSupportPatch.kt | 2 +- .../misc/gms/BaseGmsCoreSupportPatch.kt | 34 +++++++++++-------- .../gms/BaseGmsCoreSupportResourcePatch.kt | 1 - .../fingerprints/GmsCoreSupportFingerprint.kt | 4 +-- .../misc/announcements/AnnouncementsPatch.kt | 23 +++++-------- .../youtube/misc/gms/GmsCoreSupportPatch.kt | 6 ++-- .../MainActivityOnCreateFingerprint.kt | 14 ++++++++ .../resources/addresources/values/strings.xml | 9 +++-- 8 files changed, 54 insertions(+), 39 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt 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 65d905396..060d3447c 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 @@ -34,5 +34,5 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( PrimeMethodFingerprint, ), ) { - override val gmsCoreVendor by gmsCoreVendorGroupIdOption + override val gmsCoreVendorGroupId 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 f7bfcb6ef..9d2544b7e 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 @@ -2,7 +2,7 @@ package app.revanced.patches.shared.misc.gms import app.revanced.patcher.PatchClass 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.getInstructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.fingerprint.MethodFingerprint @@ -12,7 +12,7 @@ import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AC import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AUTHORITIES import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.PERMISSIONS import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint -import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_METHOD_NAME +import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.returnEarly @@ -32,7 +32,7 @@ import com.android.tools.smali.dexlib2.util.MethodUtil * @param toPackageName The package name to fall back to if no custom package name is specified in patch options. * @param primeMethodFingerprint The fingerprint of the "prime" method that needs to be patched. * @param earlyReturnFingerprints The fingerprints of methods that need to be returned early. - * @param mainActivityOnCreateFingerprint The fingerprint of the main activity's onCreate method. + * @param mainActivityOnCreateFingerprint The fingerprint of the main activity onCreate method. * @param integrationsPatchDependency The patch responsible for the integrations. * @param gmsCoreSupportResourcePatch The corresponding resource patch that is used to patch the resources. * @param dependencies Additional dependencies of this patch. @@ -60,7 +60,10 @@ abstract class BaseGmsCoreSupportPatch( integrationsPatchDependency, ) + dependencies, compatiblePackages = compatiblePackages, - fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints, + fingerprints = setOf( + GmsCoreSupportFingerprint, + mainActivityOnCreateFingerprint, + ) + fingerprints, requiresIntegrations = true, ) { init { @@ -68,7 +71,7 @@ abstract class BaseGmsCoreSupportPatch( gmsCoreSupportResourcePatch.options.values.forEach(options::register) } - internal abstract val gmsCoreVendor: String? + internal abstract val gmsCoreVendorGroupId: String? override fun execute(context: BytecodeContext) { val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName) @@ -93,16 +96,17 @@ abstract class BaseGmsCoreSupportPatch( // Return these methods early to prevent the app from crashing. earlyReturnFingerprints.toList().returnEarly() - // 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/shared/GmsCoreSupport;->checkAvailability()V", + // Verify GmsCore is installed and whitelisted for power optimizations and background usage. + mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions( + 1, // Hack to not disturb other patches (such as the YTMusic integrations patch). + "invoke-static/range { p0 .. p0 }, Lapp/revanced/integrations/shared/GmsCoreSupport;->" + + "checkGmsCore(Landroid/content/Context;)V", ) ?: throw mainActivityOnCreateFingerprint.exception // Change the vendor of GmsCore in ReVanced Integrations. GmsCoreSupportFingerprint.result?.mutableClass?.methods - ?.single { it.name == GET_GMS_CORE_VENDOR_METHOD_NAME } - ?.replaceInstruction(0, "const-string v0, \"$gmsCoreVendor\"") + ?.single { it.name == GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME } + ?.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"") ?: throw GmsCoreSupportFingerprint.exception } @@ -146,10 +150,10 @@ abstract class BaseGmsCoreSupportPatch( in PERMISSIONS, in ACTIONS, in AUTHORITIES, - -> referencedString.replace("com.google", gmsCoreVendor!!) + -> referencedString.replace("com.google", gmsCoreVendorGroupId!!) // No vendor prefix for whatever reason... - "subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds" + "subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds" else -> null } @@ -162,7 +166,7 @@ abstract class BaseGmsCoreSupportPatch( if (str.startsWith(uriPrefix)) { return str.replace( uriPrefix, - "content://${authority.replace("com.google", gmsCoreVendor!!)}", + "content://${authority.replace("com.google", gmsCoreVendorGroupId!!)}", ) } } @@ -170,7 +174,7 @@ abstract class BaseGmsCoreSupportPatch( // gms also has a 'subscribedfeeds' authority, check for that one too val subFeedsUriPrefix = "content://subscribedfeeds" if (str.startsWith(subFeedsUriPrefix)) { - return str.replace(subFeedsUriPrefix, "content://$gmsCoreVendor.subscribedfeeds") + return str.replace(subFeedsUriPrefix, "content://$gmsCoreVendorGroupId.subscribedfeeds") } } 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 eef039f74..f77a6d361 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 @@ -121,7 +121,6 @@ abstract class BaseGmsCoreSupportResourcePatch( } 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/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt index 79be107f9..52cef8fd6 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GmsCoreSupportFingerprint.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint internal object GmsCoreSupportFingerprint : MethodFingerprint( customFingerprint = { _, classDef -> classDef.type.endsWith("GmsCoreSupport;") - } + }, ) { - const val GET_GMS_CORE_VENDOR_METHOD_NAME = "getGmsCoreVendor" + const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId" } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt index f7b43a2b6..434ddcaa2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt @@ -2,16 +2,14 @@ package app.revanced.patches.youtube.misc.announcements import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint -import app.revanced.util.exception -import com.android.tools.smali.dexlib2.Opcode +import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint +import app.revanced.util.resultOrThrow @Patch( name = "Announcements", @@ -21,7 +19,7 @@ import com.android.tools.smali.dexlib2.Opcode ) @Suppress("unused") object AnnouncementsPatch : BytecodePatch( - setOf(MainActivityFingerprint) + setOf(MainActivityOnCreateFingerprint) ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch;" @@ -33,16 +31,11 @@ object AnnouncementsPatch : BytecodePatch( SwitchPreference("revanced_announcements") ) - val onCreateMethod = MainActivityFingerprint.result?.let { - it.mutableClass.methods.find { method -> method.name == "onCreate" } - } ?: throw MainActivityFingerprint.exception - - val superCallIndex = onCreateMethod.getInstructions().indexOfFirst { it.opcode == Opcode.INVOKE_SUPER_RANGE } - - onCreateMethod.addInstructions( - superCallIndex + 1, - "invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V" + MainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions( + // Insert index must be great than the insert index used by GmsCoreSupport, + // as both patch the same method and GmsCore check should be first. + 1, + "invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V" ) - } } 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 ff2902351..6547f0ec3 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 @@ -9,7 +9,7 @@ import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME 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 +import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint @Suppress("unused") object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( @@ -23,7 +23,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, ), - mainActivityOnCreateFingerprint = HomeActivityFingerprint, + mainActivityOnCreateFingerprint = MainActivityOnCreateFingerprint, integrationsPatchDependency = IntegrationsPatch::class, dependencies = setOf( HideCastButtonPatch::class, @@ -57,5 +57,5 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( PrimeMethodFingerprint, ), ) { - override val gmsCoreVendor by gmsCoreVendorGroupIdOption + override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption } diff --git a/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt new file mode 100644 index 000000000..fa63c0fde --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/shared/fingerprints/MainActivityOnCreateFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.shared.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object MainActivityOnCreateFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("Landroid/os/Bundle;"), + customFingerprint = { methodDef, classDef -> + methodDef.name == "onCreate" && + (classDef.type.endsWith("MainActivity;") + // Old versions of YouTube called this class "WatchWhileActivity" instead. + || classDef.type.endsWith("WatchWhileActivity;")) + } +) \ No newline at end of file diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index d7ac91cf7..b58754755 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -13,8 +13,12 @@ Import failed: %s - GmsCore is not installed. Please install. - GmsCore is failing to run. Please follow the \"Don\'t kill my app\" guide for GmsCore. + GmsCore is not installed. Install it. + Follow the \"Don\'t kill my app\" guide for GmsCore. + Action needed + GmsCore is not whitelisted from battery optimization.\n\nFollow the \"Don\'t kill my app\" guide for GmsCore. + GmsCore does not have permission to run in the background.\n\nFollow the \"Don\'t kill my app\" guide for GmsCore. + Open website @@ -881,6 +885,7 @@ Announcements are not shown on startup Show announcements on startup Failed connecting to announcements provider + Dismiss Enable auto-repeat