mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-27 12:41:03 +00:00
some more migrations
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.music.misc.gms
|
||||
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.Option
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
@@ -19,7 +20,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = MUSIC_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_MUSIC_PACKAGE_NAME,
|
||||
getPrimeMethod = { primeMethod },
|
||||
getEarlyReturnMethods = { setOf(castContextFetchMethod) },
|
||||
earlyReturnMethods = setOf(BytecodePatchContext::castContextFetchMethod::get),
|
||||
getMainActivityOnCreateMethod = { musicActivityOnCreateMethod },
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
@@ -28,8 +29,8 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
compatibleWith(
|
||||
MUSIC_PACKAGE_NAME(
|
||||
"7.29.52",
|
||||
"8.10.52"
|
||||
)
|
||||
"8.10.52",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,17 +51,17 @@ private fun gmsCoreSupportResourcePatch(
|
||||
"microg_settings",
|
||||
intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") {
|
||||
"$gmsCoreVendorGroupId.android.gms"
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
) {
|
||||
dependsOn(
|
||||
addResourcesPatch,
|
||||
settingsPatch,
|
||||
fileProviderPatch(
|
||||
MUSIC_PACKAGE_NAME,
|
||||
REVANCED_MUSIC_PACKAGE_NAME
|
||||
)
|
||||
REVANCED_MUSIC_PACKAGE_NAME,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ internal fun baseCustomBrandingPatch(
|
||||
)
|
||||
|
||||
// Bundled icons.
|
||||
iconStyleNames.forEachIndexed { index, style ->
|
||||
iconStyleNames.forEach { style ->
|
||||
application.appendChild(
|
||||
createAlias(
|
||||
aliasName = aliasName(style),
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
package app.revanced.patches.shared.layout.branding
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.numberOfPresetAppNamesExtensionMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.numberOfPresetAppNamesExtensionMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("numberOfPresetAppNames")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returnType("I")
|
||||
parameterTypes()
|
||||
custom { method, classDef ->
|
||||
method.name == "numberOfPresetAppNames" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
// A much simpler fingerprint exists that can set the small icon (contains string "414843287017"),
|
||||
// but that has limited usage and this fingerprint allows changing any part of the notification.
|
||||
internal val BytecodePatchContext.notificationMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.notificationMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"key_action_priority",
|
||||
) {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameterTypes("L")
|
||||
strings("key_action_priority")
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package app.revanced.patches.shared.misc.gms
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.googlePlayUtilityMethod by gettingFirstMethodDeclaratively(
|
||||
internal val BytecodePatchContext.googlePlayUtilityMethod by gettingFirstMutableMethodDeclarativelyOrNull(
|
||||
"This should never happen.",
|
||||
"MetadataValueReader",
|
||||
"com.google.android.gms",
|
||||
@@ -17,7 +14,7 @@ internal val BytecodePatchContext.googlePlayUtilityMethod by gettingFirstMethodD
|
||||
parameterTypes("L", "I")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.serviceCheckMethod by gettingFirstMethodDeclaratively(
|
||||
internal val BytecodePatchContext.serviceCheckMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"Google Play Services not available",
|
||||
) {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
@@ -25,20 +22,18 @@ internal val BytecodePatchContext.serviceCheckMethod by gettingFirstMethodDeclar
|
||||
parameterTypes("L", "I")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.gmsCoreSupportMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.gmsCoreSupportMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getGmsCoreVendorGroupId")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes()
|
||||
custom { method, classDef ->
|
||||
method.name == "getGmsCoreVendorGroupId" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.originalPackageNameExtensionMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.originalPackageNameExtensionMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getOriginalPackageName")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes()
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "getOriginalPackageName" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patches.all.misc.packagename.`Change package name`
|
||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
@@ -36,7 +35,7 @@ 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 getPrimeMethod The "prime" method that needs to be patched.
|
||||
* @param getEarlyReturnMethods The methods that need to be returned early.
|
||||
* @param earlyReturnMethods 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
|
||||
@@ -48,7 +47,7 @@ fun gmsCoreSupportPatch(
|
||||
fromPackageName: String,
|
||||
toPackageName: String,
|
||||
getPrimeMethod: (BytecodePatchContext.() -> MutableMethod)? = null,
|
||||
getEarlyReturnMethods: Set<BytecodePatchContext.() -> MutableMethod> = emptySet(),
|
||||
earlyReturnMethods: Set<BytecodePatchContext.() -> MutableMethod> = emptySet(),
|
||||
getMainActivityOnCreateMethod: BytecodePatchContext.() -> MutableMethod,
|
||||
extensionPatch: Patch,
|
||||
gmsCoreSupportResourcePatchFactory: (gmsCoreVendorGroupIdOption: Option<String>) -> Patch,
|
||||
@@ -203,13 +202,11 @@ fun gmsCoreSupportPatch(
|
||||
getPrimeMethod?.let { transformPrimeMethod(packageName) }
|
||||
|
||||
// Return these methods early to prevent the app from crashing.
|
||||
getEarlyReturnMethods().forEach { it.returnEarly() }
|
||||
earlyReturnMethods.forEach { it().returnEarly() }
|
||||
serviceCheckMethod.returnEarly()
|
||||
|
||||
// Google Play Utility is not present in all apps, so we need to check if it's present.
|
||||
if (googlePlayUtilityMethodOrNull != null) {
|
||||
googlePlayUtilityMethod.returnEarly(0)
|
||||
}
|
||||
googlePlayUtilityMethod?.returnEarly(0)
|
||||
|
||||
// Set original and patched package names for extension to use.
|
||||
originalPackageNameExtensionMethod.returnEarly(fromPackageName)
|
||||
|
||||
@@ -22,7 +22,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME,
|
||||
getPrimeMethod = BytecodePatchContext::primeMethod::get,
|
||||
getEarlyReturnMethods = setOf(BytecodePatchContext::castContextFetchMethod::get),
|
||||
earlyReturnMethods = setOf(BytecodePatchContext::castContextFetchMethod::get),
|
||||
getMainActivityOnCreateMethod = BytecodePatchContext::mainActivityOnCreateMethod::get,
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
@@ -38,7 +38,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
"20.14.43",
|
||||
"20.21.37",
|
||||
"20.31.40",
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -59,14 +59,14 @@ private fun gmsCoreSupportResourcePatch(
|
||||
"microg_settings",
|
||||
intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") {
|
||||
"$gmsCoreVendorGroupId.android.gms"
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
) {
|
||||
dependsOn(
|
||||
addResourcesPatch,
|
||||
settingsPatch,
|
||||
accountCredentialsInvalidTextPatch
|
||||
accountCredentialsInvalidTextPatch,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
package app.revanced.patches.youtube.misc.playercontrols
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.checkCast
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.methodCall
|
||||
import app.revanced.patcher.opcode
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
internal val BytecodePatchContext.playerControlsVisibilityEntityModelMethod by gettingFirstMethodDeclaratively {
|
||||
name("getPlayerControlsVisibility")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("L")
|
||||
parameterTypes()
|
||||
@@ -23,131 +16,113 @@ internal val BytecodePatchContext.playerControlsVisibilityEntityModelMethod by g
|
||||
Opcode.IGET,
|
||||
Opcode.INVOKE_STATIC,
|
||||
)
|
||||
custom { method, _ ->
|
||||
method.name == "getPlayerControlsVisibility"
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.youtubeControlsOverlayMethod by gettingFirstMethodDeclaratively {
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
methodCall(name = "setFocusableInTouchMode"),
|
||||
method("setFocusableInTouchMode"),
|
||||
ResourceType.ID("inset_overlay_view_layout"),
|
||||
ResourceType.ID("scrim_overlay"),
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.motionEventMethod by gettingFirstMethodDeclaratively {
|
||||
internal val motionEventMethodMatch = firstMethodComposite {
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/view/MotionEvent;")
|
||||
instructions(
|
||||
methodCall(name = "setTranslationY"),
|
||||
)
|
||||
instructions(method("setTranslationY"))
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerControlsExtensionHookListenersExistMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerControlsExtensionHookListenersExistMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("fullscreenButtonVisibilityCallbacksExist")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "fullscreenButtonVisibilityCallbacksExist" &&
|
||||
classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerControlsExtensionHookMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerControlsExtensionHookMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("fullscreenButtonVisibilityChanged")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||
returnType("V")
|
||||
parameterTypes("Z")
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "fullscreenButtonVisibilityChanged" &&
|
||||
classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerTopControlsInflateMethod by gettingFirstMethodDeclaratively {
|
||||
internal val playerTopControlsInflateMethod = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
ResourceType.ID("controls_layout_stub"),
|
||||
methodCall("Landroid/view/ViewStub;", "inflate"),
|
||||
method { name == "inflate" && definingClass == "Landroid/view/ViewStub;" },
|
||||
after(Opcode.MOVE_RESULT_OBJECT()),
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerBottomControlsInflateMethod by gettingFirstMethodDeclaratively {
|
||||
internal val playerBottomControlsInflateMethodMatch = firstMethodComposite {
|
||||
returnType("Ljava/lang/Object;")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
ResourceType.ID("bottom_ui_container_stub"),
|
||||
methodCall("Landroid/view/ViewStub;", "inflate"),
|
||||
method { name == "inflate" && definingClass == "Landroid/view/ViewStub;" },
|
||||
after(Opcode.MOVE_RESULT_OBJECT()),
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.overlayViewInflateMethod by gettingFirstMethodDeclaratively {
|
||||
internal val overlayViewInflateMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/view/View;")
|
||||
instructions(
|
||||
ResourceType.ID("heatseeker_viewstub"),
|
||||
ResourceType.ID("fullscreen_button"),
|
||||
checkCast("Landroid/widget/ImageView;"),
|
||||
allOf(Opcode.CHECK_CAST(), type("Landroid/widget/ImageView;")),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves to the class found in [playerTopControlsInflateMethod].
|
||||
*/
|
||||
internal val BytecodePatchContext.controlsOverlayVisibilityMethod by gettingFirstMethodDeclaratively {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getControlsOverlayVisibilityMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes("Z", "Z")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerBottomControlsExploderFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerBottomControlsExploderFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
45643739L(),
|
||||
)
|
||||
instructions(45643739L())
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerTopControlsExperimentalLayoutFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerTopControlsExperimentalLayoutFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("I")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
45629424L(),
|
||||
)
|
||||
instructions(45629424L())
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerControlsLargeOverlayButtonsFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerControlsLargeOverlayButtonsFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
45709810L(),
|
||||
)
|
||||
instructions(45709810L())
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerControlsFullscreenLargeButtonsFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerControlsFullscreenLargeButtonsFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
45686474L(),
|
||||
)
|
||||
instructions(45686474L())
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playerControlsButtonStrokeFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerControlsButtonStrokeFeatureFlagMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
45713296L(),
|
||||
)
|
||||
instructions(45713296L())
|
||||
}
|
||||
|
||||
@@ -2,26 +2,15 @@ package app.revanced.patches.youtube.misc.playercontrols
|
||||
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patcher.util.Document
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_19_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_20_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_28_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_30_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.util.copyXmlNode
|
||||
import app.revanced.util.findElementByAttributeValue
|
||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.inputStreamFromBundledResource
|
||||
import app.revanced.util.returnEarly
|
||||
import app.revanced.util.returnLate
|
||||
import app.revanced.patches.youtube.misc.playservice.*
|
||||
import app.revanced.util.*
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
@@ -244,51 +233,44 @@ val playerControlsPatch = bytecodePatch(
|
||||
)
|
||||
|
||||
apply {
|
||||
playerBottomControlsInflateMethod.let {
|
||||
it.method.apply {
|
||||
inflateBottomControlMethod = this
|
||||
playerBottomControlsInflateMethodMatch.method.apply {
|
||||
inflateBottomControlMethod = this
|
||||
|
||||
val inflateReturnObjectIndex = it.indices.last()
|
||||
inflateBottomControlRegister = getInstruction<OneRegisterInstruction>(inflateReturnObjectIndex).registerA
|
||||
inflateBottomControlInsertIndex = inflateReturnObjectIndex + 1
|
||||
}
|
||||
val inflateReturnObjectIndex = playerBottomControlsInflateMethodMatch.indices.last()
|
||||
inflateBottomControlRegister = getInstruction<OneRegisterInstruction>(inflateReturnObjectIndex).registerA
|
||||
inflateBottomControlInsertIndex = inflateReturnObjectIndex + 1
|
||||
}
|
||||
|
||||
playerTopControlsInflateMethod.let {
|
||||
it.method.apply {
|
||||
inflateTopControlMethod = this
|
||||
playerTopControlsInflateMethod.method.apply {
|
||||
inflateTopControlMethod = this
|
||||
|
||||
val inflateReturnObjectIndex = it.indices.last()
|
||||
inflateTopControlRegister = getInstruction<OneRegisterInstruction>(inflateReturnObjectIndex).registerA
|
||||
inflateTopControlInsertIndex = inflateReturnObjectIndex + 1
|
||||
}
|
||||
val inflateReturnObjectIndex = playerTopControlsInflateMethod.indices.last()
|
||||
inflateTopControlRegister = getInstruction<OneRegisterInstruction>(inflateReturnObjectIndex).registerA
|
||||
inflateTopControlInsertIndex = inflateReturnObjectIndex + 1
|
||||
}
|
||||
|
||||
visibilityMethod = controlsOverlayVisibilityMethod.match(
|
||||
playerTopControlsInflateMethod.originalClassDef,
|
||||
).method
|
||||
visibilityMethod =
|
||||
playerTopControlsInflateMethod.immutableClassDef.getControlsOverlayVisibilityMethod()
|
||||
|
||||
// Hook the fullscreen close button. Used to fix visibility
|
||||
// when seeking and other situations.
|
||||
overlayViewInflateMethod.let {
|
||||
it.method.apply {
|
||||
val index = it.indices.last()
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
overlayViewInflateMethodMatch.method.apply {
|
||||
val index = overlayViewInflateMethodMatch.indices.last()
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, " +
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->setFullscreenCloseButton(Landroid/widget/ImageView;)V",
|
||||
)
|
||||
}
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, " +
|
||||
"$EXTENSION_CLASS_DESCRIPTOR->setFullscreenCloseButton(Landroid/widget/ImageView;)V",
|
||||
)
|
||||
}
|
||||
|
||||
visibilityImmediateCallbacksExistMethod = playerControlsExtensionHookListenersExistMethod
|
||||
visibilityImmediateMethod = playerControlsExtensionHookMethod
|
||||
|
||||
motionEventMethod.match(youtubeControlsOverlayMethod.originalClassDef).let {
|
||||
motionEventMethodMatch.match(youtubeControlsOverlayMethod.immutableClassDef).let {
|
||||
visibilityNegatedImmediateMethod = it.method
|
||||
visibilityNegatedImmediateInsertIndex = it.instructionMatches.first().index + 1
|
||||
visibilityNegatedImmediateInsertIndex = it.indices.first() + 1
|
||||
}
|
||||
|
||||
// A/B test for a slightly different bottom overlay controls,
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
package app.revanced.patches.youtube.misc.playertype
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.after
|
||||
import app.revanced.patcher.afterAtMost
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.playerTypeEnumMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.playerTypeEnumMethod by gettingFirstMethodDeclaratively(
|
||||
"NONE",
|
||||
"HIDDEN",
|
||||
"WATCH_WHILE_MINIMIZED",
|
||||
"WATCH_WHILE_MAXIMIZED",
|
||||
"WATCH_WHILE_FULLSCREEN",
|
||||
"WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN",
|
||||
"WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED",
|
||||
"WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED",
|
||||
"INLINE_MINIMAL",
|
||||
"VIRTUAL_REALITY_FULLSCREEN",
|
||||
"WATCH_WHILE_PICTURE_IN_PICTURE",
|
||||
) {
|
||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||
strings(
|
||||
"NONE",
|
||||
"HIDDEN",
|
||||
"WATCH_WHILE_MINIMIZED",
|
||||
"WATCH_WHILE_MAXIMIZED",
|
||||
"WATCH_WHILE_FULLSCREEN",
|
||||
"WATCH_WHILE_SLIDING_MAXIMIZED_FULLSCREEN",
|
||||
"WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED",
|
||||
"WATCH_WHILE_SLIDING_MINIMIZED_DISMISSED",
|
||||
"INLINE_MINIMAL",
|
||||
"VIRTUAL_REALITY_FULLSCREEN",
|
||||
"WATCH_WHILE_PICTURE_IN_PICTURE",
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.reelWatchPagerMethod by gettingFirstMethodDeclaratively {
|
||||
internal val reelWatchPagerMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Landroid/view/View;")
|
||||
instructions(
|
||||
@@ -39,17 +31,16 @@ internal val BytecodePatchContext.reelWatchPagerMethod by gettingFirstMethodDecl
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.videoStateEnumMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.videoStateEnumMethod by gettingFirstMethodDeclaratively(
|
||||
"NEW",
|
||||
"PLAYING",
|
||||
"PAUSED",
|
||||
"RECOVERABLE_ERROR",
|
||||
"UNRECOVERABLE_ERROR",
|
||||
"ENDED",
|
||||
) {
|
||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||
parameterTypes()
|
||||
strings(
|
||||
"NEW",
|
||||
"PLAYING",
|
||||
"PAUSED",
|
||||
"RECOVERABLE_ERROR",
|
||||
"UNRECOVERABLE_ERROR",
|
||||
"ENDED",
|
||||
)
|
||||
}
|
||||
|
||||
// 20.33 and lower class name ControlsState. 20.34+ class name is obfuscated.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package app.revanced.patches.youtube.misc.playertype
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.fieldAccess
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
@@ -20,54 +20,44 @@ val playerTypeHookPatch = bytecodePatch(
|
||||
dependsOn(sharedExtensionPatch, resourceMappingPatch)
|
||||
|
||||
apply {
|
||||
val playerOverlaysSetPlayerTypeFingerprint = fingerprint {
|
||||
firstMutableMethodDeclaratively {
|
||||
definingClass { endsWith("/YouTubePlayerOverlaysLayout;") }
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes(playerTypeEnumMethod.originalClassDef.type)
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("/YouTubePlayerOverlaysLayout;")
|
||||
}
|
||||
}
|
||||
|
||||
playerOverlaysSetPlayerTypeFingerprint.method.addInstruction(
|
||||
parameterTypes(playerTypeEnumMethod.immutableClassDef.type)
|
||||
}.addInstruction(
|
||||
0,
|
||||
"invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V",
|
||||
)
|
||||
|
||||
reelWatchPagerMethod.let {
|
||||
it.method.apply {
|
||||
val index = it.indices.last()
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
reelWatchPagerMethodMatch.method.apply {
|
||||
val index = reelWatchPagerMethodMatch.indices.last()
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->onShortsCreate(Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->onShortsCreate(Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
|
||||
val controlStateType = controlsStateToStringMethod.originalClassDef.type
|
||||
val controlStateType = controlsStateToStringMethod.immutableClassDef.type
|
||||
|
||||
val videoStateFingerprint = fingerprint {
|
||||
val videoStateEnumMethod = videoStateEnumMethod
|
||||
firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes(controlStateType)
|
||||
instructions(
|
||||
field {
|
||||
definingClass == controlStateType && type == videoStateEnumMethod.immutableClassDef.type
|
||||
},
|
||||
// Obfuscated parameter field name.
|
||||
fieldAccess(
|
||||
definingClass = controlStateType,
|
||||
type = videoStateEnumMethod.originalClassDef.type,
|
||||
),
|
||||
ResourceType.STRING("accessibility_play"),
|
||||
ResourceType.STRING("accessibility_pause"),
|
||||
)
|
||||
}
|
||||
|
||||
videoStateFingerprint.let {
|
||||
}.let {
|
||||
it.method.apply {
|
||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(
|
||||
it.instructionMatches.first().index,
|
||||
).reference
|
||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(it.indices.first()).reference
|
||||
|
||||
addInstructions(
|
||||
0,
|
||||
|
||||
@@ -1,50 +1,38 @@
|
||||
package app.revanced.patches.youtube.misc.settings
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.after
|
||||
import app.revanced.patcher.afterAtMost
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.opcode
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.licenseActivityOnCreateMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.licenseActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass("/LicenseActivity;")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.endsWith("/LicenseActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.setThemeMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.setThemeMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("L")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
ResourceType.STRING("app_theme_appearance_dark"),
|
||||
)
|
||||
instructions(ResourceType.STRING("app_theme_appearance_dark"))
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.cairoFragmentConfigMethod by gettingFirstMethodDeclaratively {
|
||||
internal val cairoFragmentConfigMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
instructions(
|
||||
45532100L(),
|
||||
|
||||
afterAtMost(10, Opcode.MOVE_RESULT()),
|
||||
)
|
||||
}
|
||||
|
||||
// Flag is present in 20.23, but bold icons are missing and forcing them crashes the app.
|
||||
// 20.31 is the first target with all the bold icons present.
|
||||
internal val BytecodePatchContext.boldIconsFeatureFlagMethod by gettingFirstMethodDeclaratively {
|
||||
internal val boldIconsFeatureFlagMethod = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.youtube.misc.settings
|
||||
|
||||
import app.revanced.patcher.classDef
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
@@ -239,8 +240,8 @@ val settingsPatch = bytecodePatch(
|
||||
}
|
||||
|
||||
// Add setting to force Cairo settings fragment on/off.
|
||||
cairoFragmentConfigMethod.insertLiteralOverride(
|
||||
cairoFragmentConfigMethod.instructionMatches.first().index,
|
||||
cairoFragmentConfigMethodMatch.method.insertLiteralOverride(
|
||||
cairoFragmentConfigMethodMatch.indices.first(),
|
||||
"$YOUTUBE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->useCairoSettingsFragment(Z)Z",
|
||||
)
|
||||
|
||||
@@ -249,7 +250,7 @@ val settingsPatch = bytecodePatch(
|
||||
if (is_20_31_or_greater) {
|
||||
boldIconsFeatureFlagMethod.let {
|
||||
it.method.insertLiteralOverride(
|
||||
it.instructionMatches.first().index,
|
||||
it.indices.first(),
|
||||
"$YOUTUBE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->useBoldIcons(Z)Z",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -47,20 +47,15 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
|
||||
)
|
||||
|
||||
// Used for the old type of the video quality menu.
|
||||
videoQualityBottomSheetListFragmentname = getResourceId(
|
||||
ResourceType.LAYOUT,
|
||||
"video_quality_bottom_sheet_list_fragment_title",
|
||||
)
|
||||
|
||||
videoQualityQuickMenuAdvancedMenuDescription = getResourceId(
|
||||
ResourceType.STRING,
|
||||
"video_quality_quick_menu_advanced_menu_description",
|
||||
)
|
||||
videoQualityBottomSheetListFragmentname =
|
||||
ResourceType.LAYOUT["video_quality_bottom_sheet_list_fragment_title"]
|
||||
videoQualityQuickMenuAdvancedMenuDescription =
|
||||
ResourceType.STRING["video_quality_quick_menu_advanced_menu_description"]
|
||||
|
||||
// region Patch for the old type of the video quality menu.
|
||||
// Used for regular videos when spoofing to old app version,
|
||||
// and for the Shorts quality flyout on newer app versions.
|
||||
videoQualityMenuViewInflateMethod.let {
|
||||
videoQualityMenuViewInflateMethodMatch.let {
|
||||
it.method.apply {
|
||||
val checkCastIndex = it.indices.last()
|
||||
val listViewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||
@@ -74,10 +69,10 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
|
||||
}
|
||||
|
||||
// Force YT to add the 'advanced' quality menu for Shorts.
|
||||
videoQualityMenuOptionsMethod.let {
|
||||
val patternMatch = it.instructionMatches
|
||||
val startIndex = patternMatch.first().index
|
||||
val insertIndex = patternMatch.last().index
|
||||
videoQualityMenuOptionsMethodMatch.let {
|
||||
val startIndex = it.indices.first()
|
||||
val insertIndex = it.indices.last()
|
||||
|
||||
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
|
||||
|
||||
it.method.apply {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package app.revanced.patches.youtube.video.quality
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.addString
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
@@ -12,17 +13,15 @@ import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by gettingFirstMethodDeclaratively(
|
||||
"VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT",
|
||||
) {
|
||||
returnType("V")
|
||||
instructions(
|
||||
"VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT"(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves to class found in [videoQualityItemOnClickMethod].
|
||||
*/
|
||||
internal val BytecodePatchContext.videoQualityItemOnClickMethod by gettingFirstMethodDeclaratively {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun com.android.tools.smali.dexlib2.iface.ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDeclaratively {
|
||||
name("onItemClick")
|
||||
returnType("V")
|
||||
parameterTypes(
|
||||
"Landroid/widget/AdapterView;",
|
||||
@@ -30,12 +29,9 @@ internal val BytecodePatchContext.videoQualityItemOnClickMethod by gettingFirstM
|
||||
"I",
|
||||
"J",
|
||||
)
|
||||
custom { method, _ ->
|
||||
method.name == "onItemClick"
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.videoQualityMenuOptionsMethod by gettingFirstMethodDeclaratively {
|
||||
internal val videoQualityMenuOptionsMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.STATIC)
|
||||
returnType("[L")
|
||||
parameterTypes("Landroid/content/Context", "L", "L")
|
||||
@@ -49,7 +45,7 @@ internal val BytecodePatchContext.videoQualityMenuOptionsMethod by gettingFirstM
|
||||
literal { videoQualityQuickMenuAdvancedMenuDescription }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.videoQualityMenuViewInflateMethod by gettingFirstMethodDeclaratively {
|
||||
internal val videoQualityMenuViewInflateMethodMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("L")
|
||||
parameterTypes("L", "L", "L")
|
||||
|
||||
@@ -2,6 +2,7 @@ package app.revanced.patches.youtube.video.quality
|
||||
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
@@ -64,9 +65,7 @@ val rememberVideoQualityPatch = bytecodePatch {
|
||||
onCreateHook(EXTENSION_CLASS_DESCRIPTOR, "newVideoStarted")
|
||||
|
||||
// Inject a call to remember the selected quality for Shorts.
|
||||
videoQualityItemOnClickMethod.match(
|
||||
videoQualityItemOnClickParentMethod.classDef,
|
||||
).method.addInstruction(
|
||||
videoQualityItemOnClickParentMethod.immutableClassDef.getVideoQualityItemOnClickMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static { p3 }, $EXTENSION_CLASS_DESCRIPTOR->userChangedShortsQuality(I)V",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user