mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-11 13:46:17 +00:00
migrate batch
This commit is contained in:
@@ -11,7 +11,7 @@ import app.revanced.patches.shared.misc.gms.gmsCoreSupportResourcePatch
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = MAGAZINES_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
|
||||
mainActivityOnCreateFingerprint = magazinesActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreate = magazinesActivityOnCreateFingerprint,
|
||||
extensionPatch = extensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = PHOTOS_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_PHOTOS_PACKAGE_NAME,
|
||||
mainActivityOnCreateFingerprint = homeActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreate = homeActivityOnCreateFingerprint,
|
||||
extensionPatch = extensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.gms.Constants.MUSIC_MAIN_ACTIVITY_NAME
|
||||
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
|
||||
import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint
|
||||
import app.revanced.patches.music.misc.gms.musicActivityOnCreateMethod
|
||||
import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.shared.layout.branding.EXTENSION_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.shared.layout.branding.baseCustomBrandingPatch
|
||||
@@ -62,7 +62,7 @@ val customBrandingPatch = baseCustomBrandingPatch(
|
||||
originalAppPackageName = MUSIC_PACKAGE_NAME,
|
||||
isYouTubeMusic = true,
|
||||
numberOfPresetAppNames = 5,
|
||||
mainActivityOnCreateFingerprint = musicActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreate = { musicActivityOnCreateMethod },
|
||||
mainActivityName = MUSIC_MAIN_ACTIVITY_NAME,
|
||||
activityAliasNameWithIntents = MUSIC_MAIN_ACTIVITY_NAME,
|
||||
preferenceScreen = PreferenceScreen.GENERAL,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.music.misc.dns
|
||||
|
||||
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.music.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.patches.shared.misc.dns.checkWatchHistoryDomainNameResolutionPatch
|
||||
|
||||
val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameResolutionPatch(
|
||||
@@ -18,5 +18,5 @@ val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameReso
|
||||
)
|
||||
},
|
||||
|
||||
mainActivityFingerprint = mainActivityOnCreateFingerprint
|
||||
mainActivityFingerprint = mainActivityOnCreateMethod
|
||||
)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package app.revanced.patches.music.misc.gms
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val musicActivityOnCreateFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.endsWith("/MusicActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.musicActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass("/MusicActivity;"::endsWith)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
}
|
||||
@@ -4,30 +4,26 @@ import app.revanced.patcher.patch.Option
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.fileprovider.fileProviderPatch
|
||||
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.settings.PreferenceScreen
|
||||
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||
import app.revanced.patches.music.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.music.misc.fileprovider.fileProviderPatch
|
||||
import app.revanced.patches.shared.castContextFetchFingerprint
|
||||
import app.revanced.patches.shared.castContextFetchMethod
|
||||
import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||
import app.revanced.patches.shared.primeMethodFingerprint
|
||||
import app.revanced.patches.shared.primeMethod
|
||||
|
||||
@Suppress("unused")
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = MUSIC_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_MUSIC_PACKAGE_NAME,
|
||||
primeMethodFingerprint = primeMethodFingerprint,
|
||||
earlyReturnFingerprints = setOf(
|
||||
castContextFetchFingerprint,
|
||||
),
|
||||
mainActivityOnCreateFingerprint = musicActivityOnCreateFingerprint,
|
||||
getPrimeMethod = { primeMethod },
|
||||
getEarlyReturnMethods = { setOf(castContextFetchMethod) },
|
||||
getMainActivityOnCreateMethod = { musicActivityOnCreateMethod },
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
dependsOn(spoofVideoStreamsPatch)
|
||||
|
||||
compatibleWith(
|
||||
MUSIC_PACKAGE_NAME(
|
||||
|
||||
@@ -3,14 +3,10 @@ package app.revanced.patches.music.misc.spoof
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint
|
||||
import app.revanced.patches.music.misc.gms.musicActivityOnCreateMethod
|
||||
import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||
import app.revanced.patches.music.playservice.is_7_16_or_greater
|
||||
import app.revanced.patches.music.playservice.is_7_33_or_greater
|
||||
import app.revanced.patches.music.playservice.is_8_11_or_greater
|
||||
import app.revanced.patches.music.playservice.is_8_15_or_greater
|
||||
import app.revanced.patches.music.playservice.versionCheckPatch
|
||||
import app.revanced.patches.music.playservice.*
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
@@ -18,7 +14,7 @@ import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
|
||||
|
||||
val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
|
||||
extensionClassDescriptor = "Lapp/revanced/extension/music/patches/spoof/SpoofVideoStreamsPatch;",
|
||||
mainActivityOnCreateFingerprint = musicActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { musicActivityOnCreateMethod },
|
||||
fixMediaFetchHotConfig = { is_7_16_or_greater },
|
||||
fixMediaFetchHotConfigAlternative = { is_8_11_or_greater && !is_8_15_or_greater },
|
||||
fixParsePlaybackResponseFeatureFlag = { is_7_33_or_greater },
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||
import app.revanced.patches.music.playservice.is_8_05_or_greater
|
||||
import app.revanced.patches.music.playservice.versionCheckPatch
|
||||
import app.revanced.patches.music.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.music.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.patches.shared.misc.audio.forceOriginalAudioPatch
|
||||
|
||||
@Suppress("unused")
|
||||
@@ -25,7 +25,7 @@ val forceOriginalAudioPatch = forceOriginalAudioPatch(
|
||||
)
|
||||
},
|
||||
fixUseLocalizedAudioTrackFlag = { is_8_05_or_greater },
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { mainActivityOnCreateMethod },
|
||||
subclassExtensionClassDescriptor = "Lapp/revanced/extension/music/patches/ForceOriginalAudioPatch;",
|
||||
preferenceScreen = PreferenceScreen.MISC,
|
||||
)
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package app.revanced.patches.music.shared
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
|
||||
internal const val YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE = "Lcom/google/android/apps/youtube/music/activities/MusicActivity;"
|
||||
internal const val YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE =
|
||||
"Lcom/google/android/apps/youtube/music/activities/MusicActivity;"
|
||||
|
||||
internal val mainActivityOnCreateFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.type == YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE
|
||||
}
|
||||
internal val BytecodePatchContext.mainActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass(YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,4 @@ package app.revanced.patches.reddit.customclients.baconreader.misc.extension.hoo
|
||||
|
||||
import app.revanced.patches.shared.misc.extension.activityOnCreateExtensionHook
|
||||
|
||||
internal val initHook = activityOnCreateExtensionHook(
|
||||
"Lcom/onelouder/baconreader/BaconReader;"
|
||||
)
|
||||
internal val initHook = activityOnCreateExtensionHook("Lcom/onelouder/baconreader/BaconReader;")
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package app.revanced.patches.shared
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.addString
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val castContextFetchFingerprint = fingerprint {
|
||||
instructions(
|
||||
addString("Error fetching CastContext.")
|
||||
)
|
||||
}
|
||||
internal val BytecodePatchContext.castContextFetchMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"Error fetching CastContext."
|
||||
)
|
||||
|
||||
internal val primeMethodFingerprint = fingerprint {
|
||||
instructions(
|
||||
addString("com.android.vending"),
|
||||
addString("com.google.android.GoogleCamera")
|
||||
)
|
||||
}
|
||||
internal val BytecodePatchContext.primeMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"com.android.vending",
|
||||
"com.google.android.GoogleCamera"
|
||||
)
|
||||
|
||||
@@ -1,36 +1,21 @@
|
||||
package app.revanced.patches.shared.layout.branding
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.ResourcePatchBuilder
|
||||
import app.revanced.patcher.patch.ResourcePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.*
|
||||
import app.revanced.util.Utils.trimIndentMultiline
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.removeFromParent
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.File
|
||||
@@ -81,13 +66,13 @@ internal fun baseCustomBrandingPatch(
|
||||
originalAppPackageName: String,
|
||||
isYouTubeMusic: Boolean,
|
||||
numberOfPresetAppNames: Int,
|
||||
mainActivityOnCreateFingerprint: Fingerprint,
|
||||
getMainActivityOnCreate: BytecodePatchContext.() -> MutableMethod,
|
||||
mainActivityName: String,
|
||||
activityAliasNameWithIntents: String,
|
||||
preferenceScreen: BasePreferenceScreen.Screen,
|
||||
block: ResourcePatchBuilder.() -> Unit,
|
||||
executeBlock: ResourcePatchContext.() -> Unit = {}
|
||||
): ResourcePatch = resourcePatch(
|
||||
) = resourcePatch(
|
||||
name = "Custom branding",
|
||||
description = "Adds options to change the app icon and app name. " +
|
||||
"Branding cannot be changed for mounted (root) installations."
|
||||
@@ -125,7 +110,7 @@ internal fun baseCustomBrandingPatch(
|
||||
addBrandLicensePatch,
|
||||
bytecodePatch {
|
||||
apply {
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
getMainActivityOnCreate().addInstruction(
|
||||
0,
|
||||
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setBranding()V"
|
||||
)
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
package app.revanced.patches.shared.misc.audio
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.literal
|
||||
import app.revanced.patcher.*
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val formatStreamModelToStringFingerprint = fingerprint {
|
||||
internal val formatStreamModelToStringMethodMatch = firstMethodComposite {
|
||||
name("toString")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Ljava/lang/String;")
|
||||
custom { method, _ ->
|
||||
method.name == "toString"
|
||||
}
|
||||
strings(
|
||||
// Strings are partial matches.
|
||||
"isDefaultAudioTrack=",
|
||||
"audioTrackId="
|
||||
returnType("Ljava/lang/String;")
|
||||
instructions(
|
||||
"isDefaultAudioTrack="(String::contains),
|
||||
"audioTrackId="(String::contains)
|
||||
)
|
||||
}
|
||||
|
||||
internal val selectAudioStreamFingerprint = fingerprint {
|
||||
instructions(
|
||||
literal(45666189L)
|
||||
)
|
||||
internal val selectAudioStreamMethodMatch = firstMethodComposite {
|
||||
instructions(45666189L())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.shared.misc.audio
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
@@ -8,8 +7,6 @@ import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableField.Companion.toMutable
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||
@@ -24,6 +21,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableField.Companion.toMutable
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/patches/ForceOriginalAudioPatch;"
|
||||
@@ -35,7 +35,7 @@ internal fun forceOriginalAudioPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
fixUseLocalizedAudioTrackFlag: BytecodePatchContext.() -> Boolean,
|
||||
mainActivityOnCreateFingerprint: Fingerprint,
|
||||
getMainActivityOnCreateMethod: BytecodePatchContext.() -> MutableMethod,
|
||||
subclassExtensionClassDescriptor: String,
|
||||
preferenceScreen: BasePreferenceScreen.Screen
|
||||
) = bytecodePatch(
|
||||
@@ -57,7 +57,7 @@ internal fun forceOriginalAudioPatch(
|
||||
)
|
||||
)
|
||||
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
getMainActivityOnCreateMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static { }, $subclassExtensionClassDescriptor->setEnabled()V"
|
||||
)
|
||||
@@ -65,90 +65,91 @@ internal fun forceOriginalAudioPatch(
|
||||
// Disable feature flag that ignores the default track flag
|
||||
// and instead overrides to the user region language.
|
||||
if (fixUseLocalizedAudioTrackFlag()) {
|
||||
selectAudioStreamFingerprint.method.insertLiteralOverride(
|
||||
selectAudioStreamFingerprint.instructionMatches.first().index,
|
||||
selectAudioStreamMethodMatch.method.insertLiteralOverride(
|
||||
selectAudioStreamMethodMatch.indices.first(),
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->ignoreDefaultAudioStream(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
formatStreamModelToStringFingerprint.let {
|
||||
val isDefaultAudioTrackMethod = it.originalMethod.findMethodFromToString("isDefaultAudioTrack=")
|
||||
val audioTrackDisplayNameMethod = it.originalMethod.findMethodFromToString("audioTrackDisplayName=")
|
||||
val audioTrackIdMethod = it.originalMethod.findMethodFromToString("audioTrackId=")
|
||||
val isDefaultAudioTrackMethod =
|
||||
formatStreamModelToStringMethodMatch.immutableMethod.findMethodFromToString("isDefaultAudioTrack=")
|
||||
val audioTrackDisplayNameMethod =
|
||||
formatStreamModelToStringMethodMatch.immutableMethod.findMethodFromToString("audioTrackDisplayName=")
|
||||
val audioTrackIdMethod =
|
||||
formatStreamModelToStringMethodMatch.immutableMethod.findMethodFromToString("audioTrackId=")
|
||||
|
||||
it.classDef.apply {
|
||||
// Add a new field to store the override.
|
||||
val helperFieldName = "patch_isDefaultAudioTrackOverride"
|
||||
fields.add(
|
||||
ImmutableField(
|
||||
type,
|
||||
helperFieldName,
|
||||
"Ljava/lang/Boolean;",
|
||||
// Boolean is a 100% immutable class (all fields are final)
|
||||
// and safe to write to a shared field without volatile/synchronization,
|
||||
// but without volatile the field can show stale data
|
||||
// and the same field is calculated more than once by different threads.
|
||||
AccessFlags.PRIVATE.value or AccessFlags.VOLATILE.value,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).toMutable()
|
||||
formatStreamModelToStringMethodMatch.classDef.apply {
|
||||
// Add a new field to store the override.
|
||||
val helperFieldName = "patch_isDefaultAudioTrackOverride"
|
||||
fields.add(
|
||||
ImmutableField(
|
||||
type,
|
||||
helperFieldName,
|
||||
"Ljava/lang/Boolean;",
|
||||
// Boolean is a 100% immutable class (all fields are final)
|
||||
// and safe to write to a shared field without volatile/synchronization,
|
||||
// but without volatile the field can show stale data
|
||||
// and the same field is calculated more than once by different threads.
|
||||
AccessFlags.PRIVATE.value or AccessFlags.VOLATILE.value,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).toMutable()
|
||||
)
|
||||
|
||||
// Add a helper method because the isDefaultAudioTrack() has only 2 registers and 3 are needed.
|
||||
val helperMethodClass = type
|
||||
val helperMethodName = "patch_isDefaultAudioTrack"
|
||||
val helperMethod = ImmutableMethod(
|
||||
helperMethodClass,
|
||||
helperMethodName,
|
||||
listOf(ImmutableMethodParameter("Z", null, null)),
|
||||
"Z",
|
||||
AccessFlags.PRIVATE.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(6),
|
||||
).toMutable().apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
iget-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean;
|
||||
if-eqz v0, :call_extension
|
||||
invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z
|
||||
move-result v3
|
||||
return v3
|
||||
|
||||
:call_extension
|
||||
invoke-virtual { p0 }, $audioTrackIdMethod
|
||||
move-result-object v1
|
||||
|
||||
invoke-virtual { p0 }, $audioTrackDisplayNameMethod
|
||||
move-result-object v2
|
||||
|
||||
invoke-static { p1, v1, v2 }, $EXTENSION_CLASS_DESCRIPTOR->isDefaultAudioStream(ZLjava/lang/String;Ljava/lang/String;)Z
|
||||
move-result v3
|
||||
|
||||
invoke-static { v3 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
|
||||
move-result-object v0
|
||||
iput-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean;
|
||||
return v3
|
||||
"""
|
||||
)
|
||||
}
|
||||
methods.add(helperMethod)
|
||||
|
||||
// Add a helper method because the isDefaultAudioTrack() has only 2 registers and 3 are needed.
|
||||
val helperMethodClass = type
|
||||
val helperMethodName = "patch_isDefaultAudioTrack"
|
||||
val helperMethod = ImmutableMethod(
|
||||
helperMethodClass,
|
||||
helperMethodName,
|
||||
listOf(ImmutableMethodParameter("Z", null, null)),
|
||||
"Z",
|
||||
AccessFlags.PRIVATE.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(6),
|
||||
).toMutable().apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
iget-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean;
|
||||
if-eqz v0, :call_extension
|
||||
invoke-virtual { v0 }, Ljava/lang/Boolean;->booleanValue()Z
|
||||
move-result v3
|
||||
return v3
|
||||
|
||||
:call_extension
|
||||
invoke-virtual { p0 }, $audioTrackIdMethod
|
||||
move-result-object v1
|
||||
|
||||
invoke-virtual { p0 }, $audioTrackDisplayNameMethod
|
||||
move-result-object v2
|
||||
|
||||
invoke-static { p1, v1, v2 }, $EXTENSION_CLASS_DESCRIPTOR->isDefaultAudioStream(ZLjava/lang/String;Ljava/lang/String;)Z
|
||||
move-result v3
|
||||
|
||||
invoke-static { v3 }, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
|
||||
move-result-object v0
|
||||
iput-object v0, p0, $helperMethodClass->$helperFieldName:Ljava/lang/Boolean;
|
||||
return v3
|
||||
"""
|
||||
)
|
||||
}
|
||||
methods.add(helperMethod)
|
||||
// Modify isDefaultAudioTrack() to call extension helper method.
|
||||
isDefaultAudioTrackMethod.apply {
|
||||
val index = indexOfFirstInstructionOrThrow(Opcode.RETURN)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
// Modify isDefaultAudioTrack() to call extension helper method.
|
||||
isDefaultAudioTrackMethod.apply {
|
||||
val index = indexOfFirstInstructionOrThrow(Opcode.RETURN)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstructions(
|
||||
index,
|
||||
"""
|
||||
addInstructions(
|
||||
index,
|
||||
"""
|
||||
invoke-direct { p0, v$register }, $helperMethodClass->$helperMethodName(Z)Z
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/shared/
|
||||
*/
|
||||
fun sharedExtensionPatch(
|
||||
extensionName: String,
|
||||
vararg hooks: () -> ExtensionHook,
|
||||
vararg hooks: ExtensionHook,
|
||||
) = bytecodePatch {
|
||||
dependsOn(sharedExtensionPatch(*hooks))
|
||||
dependsOn(sharedExtensionPatch(hooks = hooks))
|
||||
|
||||
extendWith("extensions/$extensionName.rve")
|
||||
}
|
||||
@@ -34,7 +34,7 @@ fun sharedExtensionPatch(
|
||||
* commonly for the onCreate method of exported activities.
|
||||
*/
|
||||
fun sharedExtensionPatch(
|
||||
vararg hooks: () -> ExtensionHook,
|
||||
vararg hooks: ExtensionHook,
|
||||
) = bytecodePatch {
|
||||
extendWith("extensions/shared.rve")
|
||||
|
||||
@@ -45,7 +45,7 @@ fun sharedExtensionPatch(
|
||||
|
||||
afterDependents {
|
||||
// The hooks are made in afterDependents to ensure that the context is hooked before any other patches.
|
||||
hooks.forEach { hook -> hook()(EXTENSION_CLASS_DESCRIPTOR) }
|
||||
hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) }
|
||||
|
||||
// Modify Utils method to include the patches release version.
|
||||
/**
|
||||
@@ -87,9 +87,9 @@ class ExtensionHook internal constructor(
|
||||
private val getContextRegister: Method.() -> String,
|
||||
private val predicate: DeclarativePredicate<Method>,
|
||||
) {
|
||||
context(context: BytecodePatchContext)
|
||||
context(_: BytecodePatchContext)
|
||||
operator fun invoke(extensionClassDescriptor: String) {
|
||||
val method = context.firstMutableMethodDeclaratively(predicate = predicate)
|
||||
val method = firstMutableMethodDeclaratively(predicate = predicate)
|
||||
val insertIndex = method.getInsertIndex()
|
||||
val contextRegister = method.getContextRegister()
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.shared.misc.gms
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
@@ -20,6 +19,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.Node
|
||||
@@ -34,9 +34,9 @@ private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
|
||||
*
|
||||
* @param fromPackageName The package name of the original app.
|
||||
* @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 onCreate method.
|
||||
* @param getPrimeMethod The "prime" method that needs to be patched.
|
||||
* @param getEarlyReturnMethods The methods that need to be returned early.
|
||||
* @param getMainActivityOnCreateMethod The main activity onCreate method.
|
||||
* @param extensionPatch The patch responsible for the extension.
|
||||
* @param gmsCoreSupportResourcePatchFactory The factory for the corresponding resource patch
|
||||
* that is used to patch the resources.
|
||||
@@ -46,9 +46,9 @@ private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
|
||||
fun gmsCoreSupportPatch(
|
||||
fromPackageName: String,
|
||||
toPackageName: String,
|
||||
primeMethodFingerprint: Fingerprint? = null,
|
||||
earlyReturnFingerprints: Set<Fingerprint> = setOf(),
|
||||
mainActivityOnCreateFingerprint: Fingerprint,
|
||||
getPrimeMethod: (BytecodePatchContext.() -> MutableMethod)? = null,
|
||||
getEarlyReturnMethods: BytecodePatchContext.() -> Set<MutableMethod> = { setOf() },
|
||||
getMainActivityOnCreateMethod: BytecodePatchContext.() -> MutableMethod,
|
||||
extensionPatch: Patch,
|
||||
gmsCoreSupportResourcePatchFactory: (gmsCoreVendorGroupIdOption: Option<String>) -> Patch,
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
@@ -165,18 +165,18 @@ fun gmsCoreSupportPatch(
|
||||
}
|
||||
|
||||
fun transformPrimeMethod(packageName: String) {
|
||||
primeMethodFingerprint!!.method.apply {
|
||||
var register = 2
|
||||
val primeMethod = getPrimeMethod!!()
|
||||
|
||||
val index = instructions.indexOfFirst {
|
||||
if (it.getReference<StringReference>()?.string != fromPackageName) return@indexOfFirst false
|
||||
var register = 2
|
||||
|
||||
register = (it as OneRegisterInstruction).registerA
|
||||
return@indexOfFirst true
|
||||
}
|
||||
val index = primeMethod.instructions.indexOfFirst {
|
||||
if (it.getReference<StringReference>()?.string != fromPackageName) return@indexOfFirst false
|
||||
|
||||
replaceInstruction(index, "const-string v$register, \"$packageName\"")
|
||||
register = (it as OneRegisterInstruction).registerA
|
||||
return@indexOfFirst true
|
||||
}
|
||||
|
||||
primeMethod.replaceInstruction(index, "const-string v$register, \"$packageName\"")
|
||||
}
|
||||
|
||||
// endregion
|
||||
@@ -198,18 +198,10 @@ fun gmsCoreSupportPatch(
|
||||
}
|
||||
|
||||
// Specific method that needs to be patched.
|
||||
primeMethodFingerprint?.let { transformPrimeMethod(packageName) }
|
||||
getPrimeMethod?.let { transformPrimeMethod(packageName) }
|
||||
|
||||
// Return these methods early to prevent the app from crashing.
|
||||
earlyReturnFingerprints.forEach {
|
||||
it.method.apply {
|
||||
if (returnType == "Z") {
|
||||
returnEarly(false)
|
||||
} else {
|
||||
returnEarly()
|
||||
}
|
||||
}
|
||||
}
|
||||
getEarlyReturnMethods().forEach { it.returnEarly() }
|
||||
serviceCheckFingerprint.method.returnEarly()
|
||||
|
||||
// Google Play Utility is not present in all apps, so we need to check if it's present.
|
||||
@@ -221,7 +213,7 @@ fun gmsCoreSupportPatch(
|
||||
originalPackageNameExtensionFingerprint.method.returnEarly(fromPackageName)
|
||||
|
||||
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
getMainActivityOnCreateMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"checkGmsCore(Landroid/app/Activity;)V"
|
||||
|
||||
@@ -1,69 +1,39 @@
|
||||
package app.revanced.patches.shared.misc.privacy
|
||||
|
||||
import app.revanced.patcher.InstructionLocation.MatchAfterImmediately
|
||||
import app.revanced.patcher.InstructionLocation.MatchAfterWithin
|
||||
import app.revanced.patcher.checkCast
|
||||
import app.revanced.patcher.fieldAccess
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.methodCall
|
||||
import app.revanced.patcher.opcode
|
||||
import app.revanced.patcher.addString
|
||||
import app.revanced.patcher.*
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val youTubeCopyTextFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("L", "Ljava/util/Map;")
|
||||
internal val youTubeCopyTextFingerprintMethodMatch = firstMethodComposite {
|
||||
returnType("V")
|
||||
parameterTypes("L", "Ljava/util/Map;")
|
||||
instructions(
|
||||
opcode(Opcode.IGET_OBJECT),
|
||||
addString("text/plain", location = MatchAfterWithin(2)),
|
||||
methodCall(
|
||||
smali = "Landroid/content/ClipData;->newPlainText(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Landroid/content/ClipData;",
|
||||
location = MatchAfterWithin(2)
|
||||
),
|
||||
opcode(Opcode.MOVE_RESULT_OBJECT, location = MatchAfterWithin(2)),
|
||||
methodCall(
|
||||
smali = "Landroid/content/ClipboardManager;->setPrimaryClip(Landroid/content/ClipData;)V",
|
||||
location = MatchAfterWithin(2)
|
||||
)
|
||||
Opcode.IGET_OBJECT(),
|
||||
after(0..2, "text/plain"()),
|
||||
after(0..2, method("newPlainText")),
|
||||
after(0..2, Opcode.MOVE_RESULT_OBJECT()),
|
||||
after(0..2, method("setPrimaryClip"))
|
||||
)
|
||||
}
|
||||
|
||||
internal val youTubeSystemShareSheetFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("L", "Ljava/util/Map;")
|
||||
internal val youTubeSystemShareSheetMethodMatch = firstMethodComposite {
|
||||
returnType("V")
|
||||
parameterTypes("L", "Ljava/util/Map;")
|
||||
instructions(
|
||||
methodCall(
|
||||
smali = "Landroid/content/Intent;->setClassName(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;"
|
||||
),
|
||||
|
||||
methodCall(
|
||||
smali = "Ljava/util/List;->iterator()Ljava/util/Iterator;",
|
||||
location = MatchAfterWithin(4)
|
||||
),
|
||||
|
||||
fieldAccess(
|
||||
opcode = Opcode.IGET_OBJECT,
|
||||
type = "Ljava/lang/String;",
|
||||
location = MatchAfterWithin(15)
|
||||
),
|
||||
|
||||
methodCall(
|
||||
smali = "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
|
||||
location = MatchAfterWithin(15)
|
||||
)
|
||||
method("setClassName"),
|
||||
after(0..4, method("iterator")),
|
||||
after(0..15, allOf(Opcode.IGET_OBJECT(), type("Ljava/lang/String;"))),
|
||||
after(0..15, method("putExtra"))
|
||||
)
|
||||
}
|
||||
|
||||
internal val youTubeShareSheetFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("L", "Ljava/util/Map;")
|
||||
internal val youTubeShareSheetMethodMatch = firstMethodComposite {
|
||||
returnType("V")
|
||||
parameterTypes("L", "Ljava/util/Map;")
|
||||
instructions(
|
||||
opcode(Opcode.IGET_OBJECT),
|
||||
checkCast("Ljava/lang/String;", location = MatchAfterImmediately()),
|
||||
opcode(Opcode.GOTO, location = MatchAfterImmediately()),
|
||||
|
||||
methodCall(smali = "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;"),
|
||||
|
||||
addString("YTShare_Logging_Share_Intent_Endpoint_Byte_Array")
|
||||
Opcode.IGET_OBJECT(),
|
||||
after(allOf(Opcode.CHECK_CAST(), type("Ljava/lang/String;"))),
|
||||
after(Opcode.GOTO()),
|
||||
method("putExtra"),
|
||||
"YTShare_Logging_Share_Intent_Endpoint_Byte_Array"()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package app.revanced.patches.shared.misc.privacy
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.MatchBuilder
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
@@ -60,8 +60,8 @@ internal fun sanitizeSharingLinksPatch(
|
||||
}
|
||||
)
|
||||
|
||||
fun Fingerprint.hookUrlString(matchIndex: Int) {
|
||||
val index = instructionMatches[matchIndex].index
|
||||
fun MatchBuilder.hookUrlString(matchIndex: Int) {
|
||||
val index = indices[matchIndex]
|
||||
val urlRegister = method.getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
method.addInstructions(
|
||||
@@ -73,8 +73,8 @@ internal fun sanitizeSharingLinksPatch(
|
||||
)
|
||||
}
|
||||
|
||||
fun Fingerprint.hookIntentPutExtra(matchIndex: Int) {
|
||||
val index = instructionMatches[matchIndex].index
|
||||
fun MatchBuilder.hookIntentPutExtra(matchIndex: Int) {
|
||||
val index = indices[matchIndex]
|
||||
val urlRegister = method.getInstruction<FiveRegisterInstruction>(index).registerE
|
||||
|
||||
method.addInstructionsAtControlFlowLabel(
|
||||
@@ -87,12 +87,12 @@ internal fun sanitizeSharingLinksPatch(
|
||||
}
|
||||
|
||||
// YouTube share sheet copy link.
|
||||
youTubeCopyTextFingerprint.hookUrlString(0)
|
||||
youTubeCopyTextFingerprintMethodMatch.hookUrlString(0)
|
||||
|
||||
// YouTube share sheet other apps.
|
||||
youTubeShareSheetFingerprint.hookIntentPutExtra(3)
|
||||
youTubeShareSheetMethodMatch.hookIntentPutExtra(3)
|
||||
|
||||
// Native system share sheet.
|
||||
youTubeSystemShareSheetFingerprint.hookIntentPutExtra(3)
|
||||
youTubeSystemShareSheetMethodMatch.hookIntentPutExtra(3)
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,48 @@
|
||||
package app.revanced.patches.shared.misc.spoof
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.patcher.literal
|
||||
import app.revanced.patcher.methodCall
|
||||
import app.revanced.patcher.addString
|
||||
import app.revanced.patcher.custom
|
||||
import app.revanced.patcher.extensions.methodReference
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.method
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal val buildInitPlaybackRequestFingerprint = fingerprint {
|
||||
returns("Lorg/chromium/net/UrlRequest\$Builder;")
|
||||
opcodes(
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IGET_OBJECT, // Moves the request URI string to a register to build the request with.
|
||||
)
|
||||
strings(
|
||||
"Content-Type",
|
||||
"Range",
|
||||
)
|
||||
}
|
||||
|
||||
internal val buildPlayerRequestURIFingerprint = fingerprint {
|
||||
returns("Ljava/lang/String;")
|
||||
opcodes(
|
||||
Opcode.INVOKE_VIRTUAL, // Register holds player request URI.
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.MONITOR_EXIT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
strings(
|
||||
"key",
|
||||
"asig",
|
||||
)
|
||||
}
|
||||
|
||||
internal val buildRequestFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Lorg/chromium/net/UrlRequest") // UrlRequest; or UrlRequest$Builder;
|
||||
internal val buildInitPlaybackRequestMatch = firstMethodComposite("Content-Type", "Range") {
|
||||
returnType("Lorg/chromium/net/UrlRequest\$Builder;")
|
||||
instructions(
|
||||
methodCall(name = "newUrlRequestBuilder")
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
Opcode.IGET_OBJECT(), // Moves the request URI string to a register to build the request with.
|
||||
)
|
||||
}
|
||||
|
||||
internal val buildPlayerRequestURIMethodMatch = firstMethodComposite("key", "asig") {
|
||||
returnType("Ljava/lang/String;")
|
||||
instructions(
|
||||
Opcode.INVOKE_VIRTUAL(), // Register holds player request URI.
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
Opcode.IPUT_OBJECT(),
|
||||
Opcode.IGET_OBJECT(),
|
||||
Opcode.MONITOR_EXIT(),
|
||||
Opcode.RETURN_OBJECT(),
|
||||
)
|
||||
}
|
||||
|
||||
internal val buildRequestMethodMatch = firstMethodComposite() {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returnType("Lorg/chromium/net/UrlRequest") // UrlRequest; or UrlRequest$Builder;
|
||||
instructions(
|
||||
method("newUrlRequestBuilder"),
|
||||
) // UrlRequest; or UrlRequest$Builder;
|
||||
custom { methodDef, _ ->
|
||||
custom {
|
||||
// Different targets have slightly different parameters
|
||||
|
||||
// Earlier targets have parameters:
|
||||
@@ -75,11 +72,11 @@ internal val buildRequestFingerprint = fingerprint {
|
||||
// Lorg/chromium/net/UrlRequest$Callback;
|
||||
// L
|
||||
|
||||
val parameterTypes = methodDef.parameterTypes
|
||||
val parameterTypes = parameterTypes
|
||||
val parameterTypesSize = parameterTypes.size
|
||||
(parameterTypesSize == 6 || parameterTypesSize == 7 || parameterTypesSize == 8) &&
|
||||
parameterTypes[1] == "Ljava/util/Map;" // URL headers.
|
||||
&& indexOfNewUrlRequestBuilderInstruction(methodDef) >= 0
|
||||
&& indexOfNewUrlRequestBuilderInstruction(this) >= 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,19 +93,19 @@ internal val protobufClassParseByteBufferFingerprint = fingerprint {
|
||||
custom { method, _ -> method.name == "parseFrom" }
|
||||
}
|
||||
|
||||
internal val createStreamingDataFingerprint = fingerprint {
|
||||
internal val createStreamingDataMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameters("L")
|
||||
opcodes(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
parameterTypes("L")
|
||||
instructions(
|
||||
Opcode.IPUT_OBJECT(),
|
||||
Opcode.IGET_OBJECT(),
|
||||
Opcode.IF_NEZ(),
|
||||
Opcode.SGET_OBJECT(),
|
||||
Opcode.IPUT_OBJECT(),
|
||||
)
|
||||
custom { method, classDef ->
|
||||
classDef.fields.any { field ->
|
||||
field.name == "a" && field.type.endsWith("/StreamingDataOuterClass\$StreamingData;")
|
||||
custom {
|
||||
immutableClassDef.fields.any { field ->
|
||||
field.name == "a" && field.type.endsWith($$"/StreamingDataOuterClass$StreamingData;")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,22 +126,22 @@ internal val buildMediaDataSourceFingerprint = fingerprint {
|
||||
)
|
||||
}
|
||||
|
||||
internal val hlsCurrentTimeFingerprint = fingerprint {
|
||||
internal val hlsCurrentTimeMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameters("Z", "L")
|
||||
parameterTypes("Z", "L")
|
||||
instructions(
|
||||
literal(45355374L) // HLS current time feature flag.
|
||||
45355374L() // HLS current time feature flag.
|
||||
)
|
||||
}
|
||||
|
||||
internal const val DISABLED_BY_SABR_STREAMING_URI_STRING = "DISABLED_BY_SABR_STREAMING_URI"
|
||||
|
||||
internal val mediaFetchEnumConstructorFingerprint = fingerprint {
|
||||
returns("V")
|
||||
strings(
|
||||
"ENABLED",
|
||||
"DISABLED_FOR_PLAYBACK",
|
||||
DISABLED_BY_SABR_STREAMING_URI_STRING
|
||||
internal val mediaFetchEnumConstructorMethodMatch = firstMethodComposite {
|
||||
returnType("V")
|
||||
instructions(
|
||||
"ENABLED"(),
|
||||
"DISABLED_FOR_PLAYBACK"(),
|
||||
DISABLED_BY_SABR_STREAMING_URI_STRING()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -169,35 +166,30 @@ internal val patchIncludedExtensionMethodFingerprint = fingerprint {
|
||||
// This code appears to replace the player config after the streams are loaded.
|
||||
// Flag is present in YouTube 19.34, but is missing Platypus stream replacement code until 19.43.
|
||||
// Flag and Platypus code is also present in newer versions of YouTube Music.
|
||||
internal val mediaFetchHotConfigFingerprint = fingerprint {
|
||||
instructions(
|
||||
literal(45645570L)
|
||||
)
|
||||
internal val mediaFetchHotConfigMethodMatch = firstMethodComposite {
|
||||
instructions(45645570L())
|
||||
}
|
||||
|
||||
// YT 20.10+, YT Music 8.11 - 8.14.
|
||||
// Flag is missing in YT Music 8.15+, and it is not known if a replacement flag/feature exists.
|
||||
internal val mediaFetchHotConfigAlternativeFingerprint = fingerprint {
|
||||
instructions(
|
||||
literal(45683169L)
|
||||
)
|
||||
internal val mediaFetchHotConfigAlternativeMethodMatch = firstMethodComposite {
|
||||
instructions(45683169L())
|
||||
}
|
||||
|
||||
// Feature flag that enables different code for parsing and starting video playback,
|
||||
// but it's exact purpose is not known. If this flag is enabled while stream spoofing
|
||||
// but its exact purpose is not known. If this flag is enabled while stream spoofing
|
||||
// then videos will never start playback and load forever.
|
||||
// Flag does not seem to affect playback if spoofing is off.
|
||||
internal val playbackStartDescriptorFeatureFlagFingerprint = fingerprint {
|
||||
parameters()
|
||||
returns("Z")
|
||||
instructions(
|
||||
literal(45665455L)
|
||||
)
|
||||
internal val playbackStartDescriptorFeatureFlagMethodMatch = firstMethodComposite() {
|
||||
parameterTypes()
|
||||
returnType("Z")
|
||||
instructions(45665455L())
|
||||
}
|
||||
|
||||
internal fun indexOfNewUrlRequestBuilderInstruction(method: Method) = method.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_VIRTUAL && reference?.definingClass == "Lorg/chromium/net/CronetEngine;"
|
||||
val reference = methodReference ?: return@indexOfFirstInstruction false
|
||||
|
||||
opcode == Opcode.INVOKE_VIRTUAL && reference.definingClass == "Lorg/chromium/net/CronetEngine;"
|
||||
&& reference.name == "newUrlRequestBuilder"
|
||||
&& reference.parameterTypes.size == 3
|
||||
&& reference.parameterTypes[0] == "Ljava/lang/String;"
|
||||
|
||||
@@ -1,25 +1,13 @@
|
||||
package app.revanced.patches.shared.misc.spoof
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.*
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.insertLiteralOverride
|
||||
import app.revanced.util.returnEarly
|
||||
import app.revanced.util.*
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
@@ -30,6 +18,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
|
||||
@@ -39,7 +29,7 @@ private var buildRequestMethodUrlRegister = -1
|
||||
|
||||
internal fun spoofVideoStreamsPatch(
|
||||
extensionClassDescriptor: String,
|
||||
mainActivityOnCreateFingerprint: Fingerprint,
|
||||
getMainActivityOnCreateMethod: BytecodePatchContext.() -> MutableMethod,
|
||||
fixMediaFetchHotConfig: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
fixMediaFetchHotConfigAlternative: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
fixParsePlaybackResponseFeatureFlag: BytecodePatchBuilder.() -> Boolean = { false },
|
||||
@@ -56,7 +46,7 @@ internal fun spoofVideoStreamsPatch(
|
||||
apply {
|
||||
addResources("shared", "misc.fix.playback.spoofVideoStreamsPatch")
|
||||
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
getMainActivityOnCreateMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static { }, $extensionClassDescriptor->setClientOrderToUse()V"
|
||||
)
|
||||
@@ -72,48 +62,44 @@ internal fun spoofVideoStreamsPatch(
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
|
||||
buildInitPlaybackRequestFingerprint.let {
|
||||
it.method.apply {
|
||||
val moveUriStringIndex = it.instructionMatches.first().index
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
buildInitPlaybackRequestMatch.method.apply {
|
||||
val moveUriStringIndex = buildInitPlaybackRequestMatch.indices.first()
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
buildPlayerRequestURIFingerprint.let {
|
||||
it.method.apply {
|
||||
val invokeToStringIndex = it.instructionMatches.first().index
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
buildPlayerRequestURIMethodMatch.method.apply {
|
||||
val invokeToStringIndex = buildPlayerRequestURIMethodMatch.indices.first()
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get replacement streams at player requests.
|
||||
|
||||
buildRequestFingerprint.method.apply {
|
||||
buildRequestMethodMatch.method.apply {
|
||||
buildRequestMethod = this
|
||||
|
||||
val newRequestBuilderIndex = buildRequestFingerprint.instructionMatches.first().index
|
||||
val newRequestBuilderIndex = buildRequestMethodMatch.indices.first()
|
||||
buildRequestMethodUrlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = findFreeRegister(newRequestBuilderIndex, buildRequestMethodUrlRegister)
|
||||
|
||||
@@ -130,21 +116,21 @@ internal fun spoofVideoStreamsPatch(
|
||||
|
||||
// region Replace the streaming data with the replacement streams.
|
||||
|
||||
createStreamingDataFingerprint.method.apply {
|
||||
createStreamingDataMethodMatch.method.apply {
|
||||
val setStreamDataMethodName = "patch_setStreamingData"
|
||||
val resultMethodType = createStreamingDataFingerprint.classDef.type
|
||||
val videoDetailsIndex = createStreamingDataFingerprint.instructionMatches.last().index
|
||||
val resultMethodType = createStreamingDataMethodMatch.classDef.type
|
||||
val videoDetailsIndex = createStreamingDataMethodMatch.indices.last()
|
||||
val videoDetailsRegister = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA
|
||||
val videoDetailsClass = getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
videoDetailsIndex + 1,
|
||||
"invoke-direct { p0, v$videoDetailsRegister }, " +
|
||||
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
|
||||
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
|
||||
)
|
||||
|
||||
val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass
|
||||
val setStreamingDataIndex = createStreamingDataFingerprint.instructionMatches.first().index
|
||||
val setStreamingDataIndex = createStreamingDataMethodMatch.indices.first()
|
||||
|
||||
val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
|
||||
.getReference<FieldReference>()!!.definingClass
|
||||
@@ -158,7 +144,7 @@ internal fun spoofVideoStreamsPatch(
|
||||
).getReference<FieldReference>()
|
||||
|
||||
// Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
|
||||
createStreamingDataFingerprint.classDef.methods.add(
|
||||
createStreamingDataMethodMatch.classDef.methods.add(
|
||||
ImmutableMethod(
|
||||
resultMethodType,
|
||||
setStreamDataMethodName,
|
||||
@@ -270,25 +256,21 @@ internal fun spoofVideoStreamsPatch(
|
||||
|
||||
// region Fix iOS livestream current time.
|
||||
|
||||
hlsCurrentTimeFingerprint.let {
|
||||
it.method.insertLiteralOverride(
|
||||
it.instructionMatches.first().index,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
||||
)
|
||||
}
|
||||
hlsCurrentTimeMethodMatch.method.insertLiteralOverride(
|
||||
hlsCurrentTimeMethodMatch.indices.first(),
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
// region Disable SABR playback.
|
||||
// If SABR is disabled, it seems 'MediaFetchHotConfig' may no longer need an override (not confirmed).
|
||||
|
||||
val (mediaFetchEnumClass, sabrFieldReference) = with(mediaFetchEnumConstructorFingerprint.method) {
|
||||
val stringIndex = mediaFetchEnumConstructorFingerprint.stringMatches.first {
|
||||
it.string == DISABLED_BY_SABR_STREAMING_URI_STRING
|
||||
}.index
|
||||
val (mediaFetchEnumClass, sabrFieldReference) = with(mediaFetchEnumConstructorMethodMatch.method) {
|
||||
val disabledBySABRStreamingUrlString = mediaFetchEnumConstructorMethodMatch.indices.last()
|
||||
|
||||
val mediaFetchEnumClass = definingClass
|
||||
val sabrFieldIndex = indexOfFirstInstructionOrThrow(stringIndex) {
|
||||
val sabrFieldIndex = indexOfFirstInstructionOrThrow(disabledBySABRStreamingUrlString) {
|
||||
opcode == Opcode.SPUT_OBJECT &&
|
||||
getReference<FieldReference>()?.type == mediaFetchEnumClass
|
||||
}
|
||||
@@ -327,30 +309,24 @@ internal fun spoofVideoStreamsPatch(
|
||||
// region turn off stream config replacement feature flag.
|
||||
|
||||
if (fixMediaFetchHotConfig()) {
|
||||
mediaFetchHotConfigFingerprint.let {
|
||||
it.method.insertLiteralOverride(
|
||||
it.instructionMatches.first().index,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
mediaFetchHotConfigMethodMatch.method.insertLiteralOverride(
|
||||
mediaFetchHotConfigMethodMatch.indices.first(),
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
if (fixMediaFetchHotConfigAlternative()) {
|
||||
mediaFetchHotConfigAlternativeFingerprint.let {
|
||||
it.method.insertLiteralOverride(
|
||||
it.instructionMatches.first().index,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
mediaFetchHotConfigAlternativeMethodMatch.method.insertLiteralOverride(
|
||||
mediaFetchHotConfigAlternativeMethodMatch.indices.first(),
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
if (fixParsePlaybackResponseFeatureFlag()) {
|
||||
playbackStartDescriptorFeatureFlagFingerprint.let {
|
||||
it.method.insertLiteralOverride(
|
||||
it.instructionMatches.first().index,
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
||||
)
|
||||
}
|
||||
playbackStartDescriptorFeatureFlagMethodMatch.method.insertLiteralOverride(
|
||||
playbackStartDescriptorFeatureFlagMethodMatch.indices.first(),
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package app.revanced.patches.twitter.misc.extension.hooks
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
|
||||
internal val applicationInitHook =
|
||||
extensionHook {
|
||||
custom { method, classDef ->
|
||||
classDef.type == "Lcom/twitter/app/TwitterApplication;" && method.name == "onCreate"
|
||||
}
|
||||
}
|
||||
internal val applicationInitHook = extensionHook {
|
||||
name("onCreate")
|
||||
definingClass("Lcom/twitter/app/TwitterApplication;")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ val customBrandingPatch = baseCustomBrandingPatch(
|
||||
originalAppPackageName = YOUTUBE_PACKAGE_NAME,
|
||||
isYouTubeMusic = false,
|
||||
numberOfPresetAppNames = 5,
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreate = mainActivityOnCreateFingerprint,
|
||||
mainActivityName = YOUTUBE_MAIN_ACTIVITY_NAME,
|
||||
activityAliasNameWithIntents = "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity",
|
||||
preferenceScreen = PreferenceScreen.GENERAL_LAYOUT,
|
||||
|
||||
@@ -12,12 +12,6 @@ import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val infocardsIncognitoMatch = firstMethodBuilder {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes("L", "J")
|
||||
instructions(string("vibrator"))
|
||||
}
|
||||
internal val infocardsIncognitoFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Ljava/lang/Boolean;")
|
||||
|
||||
@@ -3,7 +3,6 @@ package app.revanced.patches.youtube.misc.gms
|
||||
import app.revanced.patcher.patch.Option
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.castContextFetchFingerprint
|
||||
import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||
import app.revanced.patches.shared.primeMethodFingerprint
|
||||
@@ -20,11 +19,11 @@ import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME,
|
||||
primeMethodFingerprint = primeMethodFingerprint,
|
||||
earlyReturnFingerprints = setOf(
|
||||
getPrimeMethod = primeMethodFingerprint,
|
||||
getEarlyReturnMethods = setOf(
|
||||
castContextFetchFingerprint,
|
||||
),
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = mainActivityOnCreateFingerprint,
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
|
||||
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
|
||||
extensionClassDescriptor = "Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;",
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = mainActivityOnCreateFingerprint,
|
||||
fixMediaFetchHotConfig = {
|
||||
is_19_34_or_greater
|
||||
},
|
||||
|
||||
@@ -27,7 +27,7 @@ val forceOriginalAudioPatch = forceOriginalAudioPatch(
|
||||
)
|
||||
},
|
||||
fixUseLocalizedAudioTrackFlag = { is_20_07_or_greater },
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = mainActivityOnCreateFingerprint,
|
||||
subclassExtensionClassDescriptor = "Lapp/revanced/extension/youtube/patches/ForceOriginalAudioPatch;",
|
||||
preferenceScreen = PreferenceScreen.VIDEO,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user