fix: Revert previous release
The previous release depends on a version of ReVanced Patcher which prevents usage of resource patches on lower Android versions. To solve this issue temporarily, until a fix is present, the previous release is reverted.
This commit is contained in:
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.autorepeat.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AutoRepeatCompatibility
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.autorepeat.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object AutoRepeatFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.autorepeat.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object AutoRepeatParentFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
|
||||
+8
-5
@@ -7,7 +7,9 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
@@ -28,7 +30,7 @@ class AutoRepeatPatch : BytecodePatch(
|
||||
AutoRepeatParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_auto_repeat",
|
||||
@@ -40,7 +42,7 @@ class AutoRepeatPatch : BytecodePatch(
|
||||
|
||||
//Get Result from the ParentFingerprint which is the playMethod we need to get.
|
||||
val parentResult = AutoRepeatParentFingerprint.result
|
||||
?: throw PatchException("ParentFingerprint did not resolve.")
|
||||
?: return PatchResultError("ParentFingerprint did not resolve.")
|
||||
|
||||
//this one needs to be called when app/revanced/integrations/patches/AutoRepeatPatch;->shouldAutoRepeat() returns true
|
||||
val playMethod = parentResult.mutableMethod
|
||||
@@ -50,7 +52,7 @@ class AutoRepeatPatch : BytecodePatch(
|
||||
|
||||
//This is the method we search for
|
||||
val result = AutoRepeatFingerprint.result
|
||||
?: throw PatchException("FingerPrint did not resolve.")
|
||||
?: return PatchResultError("FingerPrint did not resolve.")
|
||||
val method = result.mutableMethod
|
||||
|
||||
//Instructions to add to the smali code
|
||||
@@ -65,7 +67,7 @@ class AutoRepeatPatch : BytecodePatch(
|
||||
|
||||
//Get the implementation so we can do a check for null and get instructions size.
|
||||
val implementation = method.implementation
|
||||
?: throw PatchException("No Method Implementation found!")
|
||||
?: return PatchResultError("No Method Implementation found!")
|
||||
|
||||
//Since addInstructions needs an index which starts counting at 0 and size starts counting at 1,
|
||||
//we have to remove 1 to get the latest instruction
|
||||
@@ -78,5 +80,6 @@ class AutoRepeatPatch : BytecodePatch(
|
||||
method.addInstructionsWithLabels(index, instructions)
|
||||
|
||||
//Everything worked as expected, return Success
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.misc.bottomsheet.hook.patch.BottomSheetHookResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object CreateBottomSheetFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
+8
-4
@@ -1,20 +1,22 @@
|
||||
package app.revanced.patches.youtube.misc.bottomsheet.hook.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints.CreateBottomSheetFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@DependsOn([IntegrationsPatch::class, BottomSheetHookResourcePatch::class])
|
||||
class BottomSheetHookPatch : BytecodePatch(
|
||||
listOf(CreateBottomSheetFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
CreateBottomSheetFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val returnLinearLayoutIndex = implementation!!.instructions.lastIndex
|
||||
@@ -29,7 +31,9 @@ class BottomSheetHookPatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw CreateBottomSheetFingerprint.exception
|
||||
} ?: return CreateBottomSheetFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
|
||||
+7
-3
@@ -1,16 +1,20 @@
|
||||
package app.revanced.patches.youtube.misc.bottomsheet.hook.patch
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||
|
||||
@DependsOn([ResourceMappingPatch::class])
|
||||
class BottomSheetHookResourcePatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
bottomSheetMargins = ResourceMappingPatch.resourceMappings.find { it.name == "bottom_sheet_margins" }?.id
|
||||
?: throw PatchException("Could not find resource")
|
||||
?: return PatchResultError("Could not find resource")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
|
||||
+5
-10
@@ -3,6 +3,8 @@ package app.revanced.patches.youtube.misc.debugging.patch
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
@@ -18,7 +20,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
@Description("Adds debugging options.")
|
||||
@DebuggingCompatibility
|
||||
class DebuggingPatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
app.revanced.patches.shared.settings.preference.impl.PreferenceScreen(
|
||||
"revanced_debug_preference_screen",
|
||||
@@ -30,15 +32,6 @@ class DebuggingPatch : ResourcePatch {
|
||||
StringResource("revanced_debug_summary_on", "Debug logs are enabled"),
|
||||
StringResource("revanced_debug_summary_off", "Debug logs are disabled")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_debug_protobuffer",
|
||||
StringResource(
|
||||
"revanced_debug_protobuffer_title",
|
||||
"Log protocol buffer"
|
||||
),
|
||||
StringResource("revanced_debug_protobuffer_summary_on", "Debug logs include proto buffer"),
|
||||
StringResource("revanced_debug_protobuffer_summary_off", "Debug logs do not include proto buffer")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_debug_stacktrace",
|
||||
StringResource(
|
||||
@@ -65,5 +58,7 @@ class DebuggingPatch : ResourcePatch {
|
||||
StringResource("revanced_debug_preference_screen_summary", "Enable or disable debugging options")
|
||||
)
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class FixBackToExitGestureCompatibility
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object OnBackPressedFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object RecyclerViewScrollingFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object RecyclerViewTopScrollingFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
|
||||
+16
-5
@@ -1,12 +1,15 @@
|
||||
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation.FixBackToExitGestureCompatibility
|
||||
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.OnBackPressedFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewScrollingFingerprint
|
||||
@@ -22,12 +25,12 @@ class FixBackToExitGesturePatch : BytecodePatch(
|
||||
OnBackPressedFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
RecyclerViewTopScrollingFingerprint.apply {
|
||||
resolve(
|
||||
context,
|
||||
RecyclerViewTopScrollingParentFingerprint.result?.classDef
|
||||
?: throw RecyclerViewTopScrollingParentFingerprint.exception
|
||||
?: return RecyclerViewTopScrollingParentFingerprint.toErrorResult()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -41,7 +44,15 @@ class FixBackToExitGesturePatch : BytecodePatch(
|
||||
OnBackPressedFingerprint to IntegrationsMethod(
|
||||
"p0", "onBackPressed", "Lcom/google/android/apps/youtube/app/watchwhile/WatchWhileActivity;"
|
||||
)
|
||||
).forEach { (fingerprint, target) -> fingerprint.injectCall(target) }
|
||||
).forEach { (fingerprint, target) ->
|
||||
try {
|
||||
fingerprint.injectCall(target)
|
||||
} catch (error: PatchResultError) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
@@ -68,6 +79,6 @@ class FixBackToExitGesturePatch : BytecodePatch(
|
||||
mutableMethod.addInstruction(
|
||||
scanResult.patternScanResult!!.endIndex, targetMethod.toString()
|
||||
)
|
||||
} ?: throw this.exception
|
||||
} ?: throw this.toErrorResult()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.playback.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ClientSpoofCompatibility
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object ProtobufParameterBuilderFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.misc.fix.playback.patch.SpoofSignatureVerificationResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object ScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* Resolves using the class found in [StoryboardThumbnailParentFingerprint].
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Here lies code that creates the seekbar thumbnails.
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object UserAgentHeaderBuilderFingerprint : MethodFingerprint(
|
||||
parameters = listOf("L", "L", "L"),
|
||||
|
||||
+8
-4
@@ -1,17 +1,19 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.misc.fix.playback.annotations.ClientSpoofCompatibility
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.UserAgentHeaderBuilderFingerprint
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@Name("Client spoof")
|
||||
@@ -21,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
class ClientSpoofPatch : BytecodePatch(
|
||||
listOf(UserAgentHeaderBuilderFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
UserAgentHeaderBuilderFingerprint.result?.let { result ->
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
result.mutableMethod.apply {
|
||||
@@ -30,7 +32,9 @@ class ClientSpoofPatch : BytecodePatch(
|
||||
addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"")
|
||||
}
|
||||
|
||||
} ?: throw UserAgentHeaderBuilderFingerprint.exception
|
||||
} ?: return UserAgentHeaderBuilderFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
+12
-7
@@ -1,14 +1,17 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
|
||||
@@ -17,7 +20,7 @@ import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThu
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailParentFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
@Name("Spoof signature verification")
|
||||
@Description("Spoofs the client to prevent playback issues.")
|
||||
@@ -33,7 +36,7 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
|
||||
ScrubbedPreviewLayoutFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
// hook parameter
|
||||
ProtobufParameterBuilderFingerprint.result?.let {
|
||||
@@ -52,14 +55,14 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw ProtobufParameterBuilderFingerprint.exception
|
||||
} ?: return ProtobufParameterBuilderFingerprint.toErrorResult()
|
||||
|
||||
|
||||
// When signature spoofing is enabled, the seekbar when tapped does not show
|
||||
// the video time, chapter names, or the video thumbnail.
|
||||
// Changing the value returned of this method forces all of these to show up,
|
||||
// except the thumbnails are blank, which is handled with the patch below.
|
||||
StoryboardThumbnailParentFingerprint.result ?: throw StoryboardThumbnailParentFingerprint.exception
|
||||
StoryboardThumbnailParentFingerprint.result ?: return StoryboardThumbnailParentFingerprint.toErrorResult()
|
||||
StoryboardThumbnailFingerprint.resolve(context, StoryboardThumbnailParentFingerprint.result!!.classDef)
|
||||
StoryboardThumbnailFingerprint.result?.apply {
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
@@ -81,7 +84,7 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
} ?: throw StoryboardThumbnailFingerprint.exception
|
||||
} ?: return StoryboardThumbnailFingerprint.toErrorResult()
|
||||
|
||||
|
||||
// Seekbar thumbnail now show up but are always a blank image.
|
||||
@@ -99,7 +102,9 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw ScrubbedPreviewLayoutFingerprint.exception
|
||||
} ?: return ScrubbedPreviewLayoutFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
+10
-5
@@ -1,17 +1,20 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.patch
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
|
||||
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
||||
class SpoofSignatureVerificationResourcePatch : ResourcePatch {
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_spoof_signature_verification",
|
||||
@@ -20,17 +23,19 @@ class SpoofSignatureVerificationResourcePatch : ResourcePatch {
|
||||
"App signature spoofed\\n\\n"
|
||||
+ "Side effects include:\\n"
|
||||
+ "• Ambient mode may not work\\n"
|
||||
+ "• Downloading videos may not work\\n"
|
||||
+ "• Seekbar thumbnails are always hidden"),
|
||||
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed\\n\\nVideo playback may not work"),
|
||||
+ "• Seekbar thumbnails are hidden\\n"
|
||||
+ "• Downloading videos may not work"),
|
||||
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
|
||||
StringResource("revanced_spoof_signature_verification_user_dialog_message",
|
||||
"Turning off this setting will cause video playback issues.")
|
||||
"Turning off this setting may cause playback issues.")
|
||||
)
|
||||
)
|
||||
|
||||
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
|
||||
it.type == "id" && it.name == "thumbnail"
|
||||
}.id
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.integrations.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class IntegrationsCompatibility
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* For embedded playback.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* For embedded playback inside Google Play store (and probably other situations as well).
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* For embedded playback inside the Google app (such as the in app 'discover' tab).
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* For embedded playback. Likely covers Google Play store and other Google products.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* For embedded playback inside 3rd party android app (such as 3rd party Reddit apps).
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Old API activity to embed YouTube into 3rd party Android apps.
|
||||
|
||||
+9
-1
@@ -3,9 +3,17 @@ package app.revanced.patches.youtube.misc.integrations.patch
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.patch.annotations.RequiresIntegrations
|
||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.EmbeddedPlayerControlsOverlayFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.EmbeddedPlayerFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.ApplicationInitFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.RemoteEmbedFragmentFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.RemoteEmbeddedPlayerFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.APIPlayerServiceFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerActivityFingerprint
|
||||
|
||||
@Name("Integrations")
|
||||
@IntegrationsCompatibility
|
||||
@RequiresIntegrations
|
||||
class IntegrationsPatch : AbstractIntegrationsPatch(
|
||||
"Lapp/revanced/integrations/utils/ReVancedUtils;",
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.links.annotations
|
||||
package app.revanced.patches.youtube.misc.links.open.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class OpenLinksExternallyCompatibility
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object BindSessionServiceFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object GetCustomTabPackageNameFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object InitializeCustomTabSupportFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.links.open.annotations.OpenLinksExternallyCompatibility
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.BindSessionServiceFingerprint
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.GetCustomTabPackageNameFingerprint
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.InitializeCustomTabSupportFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
|
||||
@Patch
|
||||
@Name("Open links externally")
|
||||
@Description("Open links outside of the app directly in your browser.")
|
||||
@OpenLinksExternallyCompatibility
|
||||
class OpenLinksExternallyPatch : BytecodePatch(
|
||||
listOf(
|
||||
GetCustomTabPackageNameFingerprint,
|
||||
BindSessionServiceFingerprint,
|
||||
InitializeCustomTabSupportFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_external_browser",
|
||||
StringResource("revanced_external_browser_title", "Open links in browser"),
|
||||
StringResource("revanced_external_browser_summary_on", "Opening links externally"),
|
||||
StringResource("revanced_external_browser_summary_off", "Opening links in app")
|
||||
)
|
||||
)
|
||||
|
||||
arrayOf(
|
||||
GetCustomTabPackageNameFingerprint,
|
||||
BindSessionServiceFingerprint,
|
||||
InitializeCustomTabSupportFingerprint
|
||||
).forEach {
|
||||
val result = it.result ?: return it.toErrorResult()
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1
|
||||
with(result.mutableMethod) {
|
||||
val register = (implementation!!.instructions[insertIndex - 1] as Instruction21c).registerA
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {v$register}, Lapp/revanced/integrations/patches/OpenLinksExternallyPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.links.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.links.annotations.OpenLinksExternallyCompatibility
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.util.patch.AbstractTransformInstructionsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Patch
|
||||
@Name("Open links externally")
|
||||
@Description("Open links outside of the app directly in your browser.")
|
||||
@OpenLinksExternallyCompatibility
|
||||
class OpenLinksExternallyPatch : AbstractTransformInstructionsPatch<Pair<Int, Int>>(
|
||||
) {
|
||||
override fun filterMap(
|
||||
classDef: ClassDef, method: Method, instruction: Instruction, instructionIndex: Int
|
||||
): Pair<Int, Int>? {
|
||||
if (instruction !is ReferenceInstruction) return null
|
||||
val reference = instruction.reference as? StringReference ?: return null
|
||||
|
||||
if (reference.string != "android.support.customtabs.action.CustomTabsService") return null
|
||||
|
||||
return instructionIndex to (instruction as OneRegisterInstruction).registerA
|
||||
}
|
||||
|
||||
override fun transform(mutableMethod: MutableMethod, entry: Pair<Int, Int>) {
|
||||
val (intentStringIndex, register) = entry
|
||||
|
||||
// Hook the intent string.
|
||||
mutableMethod.addInstructions(
|
||||
intentStringIndex + 1,
|
||||
"""
|
||||
invoke-static {v$register}, Lapp/revanced/integrations/patches/OpenLinksExternallyPatch;->getIntent(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_external_browser",
|
||||
StringResource("revanced_external_browser_title", "Open links in browser"),
|
||||
StringResource("revanced_external_browser_summary_on", "Opening links externally"),
|
||||
StringResource("revanced_external_browser_summary_off", "Opening links in app")
|
||||
)
|
||||
)
|
||||
|
||||
super.execute(context)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object ComponentContextParserFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object EmptyComponentBuilderFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object LithoFilterFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object ProtobufBufferReferenceFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object ReadComponentIdentifierFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
|
||||
+54
-28
@@ -1,6 +1,6 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
@@ -9,17 +9,23 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.immutable.ImmutableField
|
||||
import java.io.Closeable
|
||||
|
||||
@DependsOn([IntegrationsPatch::class])
|
||||
@@ -35,47 +41,59 @@ class LithoFilterPatch : BytecodePatch(
|
||||
* Additionally, the method contains a reference to the components identifier.
|
||||
* The identifier is used to filter components by their identifier.
|
||||
*
|
||||
* The protobuf buffer is passed along from a different injection point before the filtering occurs.
|
||||
* The buffer is a large byte array that represents the component tree.
|
||||
* In addition to that, a static field is added to the class of this method. (See protobufBufferField).
|
||||
* This field holds a reference to the protobuf buffer object.
|
||||
* The field is being set in another method that holds a reference to the protobuf buffer object.
|
||||
* The object contains a large byte array that represents the component tree.
|
||||
* This byte array is searched for strings that indicate the current component.
|
||||
*
|
||||
* The following pseudo code shows how the patch works:
|
||||
*
|
||||
* class SomeOtherClass {
|
||||
* // Called before ComponentContextParser.parseBytesToComponentContext method.
|
||||
* public void someOtherMethod(ByteBuffer byteBuffer) {
|
||||
* IntegrationsClass.setProtoBuffer(byteBuffer); // Inserted by this patch.
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* class ComponentContextParser {
|
||||
* public static ByteBuffer buffer; // Inserted by this patch.
|
||||
*
|
||||
* public ComponentContext parseBytesToComponentContext(...) {
|
||||
* ...
|
||||
* if (IntegrationsClass.filter(identifier, pathBuilder)); // Inserted by this patch.
|
||||
* if (filter(identifier, pathBuilder, buffer)); // Inserted by this patch.
|
||||
* return emptyComponent;
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* class SomeOtherClass {
|
||||
* // Called before ComponentContextParser.parseBytesToComponentContext method.
|
||||
* public void someOtherMethod(ByteBuffer byteBuffer) {
|
||||
* ComponentContextParser.buffer = byteBuffer; // Inserted by this patch.
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
ComponentContextParserFingerprint.result?.also {
|
||||
arrayOf(
|
||||
EmptyComponentBuilderFingerprint,
|
||||
ReadComponentIdentifierFingerprint
|
||||
).forEach { fingerprint ->
|
||||
if (fingerprint.resolve(context, it.mutableMethod, it.mutableClass)) return@forEach
|
||||
throw fingerprint.exception
|
||||
return fingerprint.toErrorResult()
|
||||
}
|
||||
}?.let { bytesToComponentContextMethod ->
|
||||
// region Add a static field that holds a reference to the protobuf buffer object.
|
||||
val protobufBufferField = ImmutableField(
|
||||
bytesToComponentContextMethod.mutableClass.type,
|
||||
"buffer",
|
||||
"Ljava/nio/ByteBuffer;",
|
||||
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
).toMutable()
|
||||
bytesToComponentContextMethod.mutableClass.staticFields.add(protobufBufferField)
|
||||
|
||||
// region Pass the buffer into Integrations.
|
||||
|
||||
// Set the field with the reference to the protobuf buffer object.
|
||||
ProtobufBufferReferenceFingerprint.result
|
||||
?.mutableMethod?.addInstruction(0,
|
||||
" invoke-static { p2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->setProtoBuffer(Ljava/nio/ByteBuffer;)V")
|
||||
?: throw ProtobufBufferReferenceFingerprint.exception
|
||||
?.mutableMethod?.addInstruction(0, "sput-object p2, $protobufBufferField")
|
||||
?: return ProtobufBufferReferenceFingerprint.toErrorResult()
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -117,13 +135,17 @@ class LithoFilterPatch : BytecodePatch(
|
||||
// region Patch the method.
|
||||
|
||||
// Insert the instructions that are responsible
|
||||
// to return an EmptyComponent instead of the original component if the filter method returns true.
|
||||
// to return an EmptyComponent instead of the original component if the filter method returns false.
|
||||
addInstructionsWithLabels(
|
||||
insertHookIndex,
|
||||
"""
|
||||
# Register "free1" holds the protobuf buffer object
|
||||
|
||||
sget-object v$free1, $protobufBufferField
|
||||
|
||||
# Invoke the filter method.
|
||||
|
||||
invoke-static { v$identifierRegister, v$stringBuilderRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z
|
||||
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free1 }, $FILTER_METHOD_DESCRIPTOR
|
||||
move-result v$free1
|
||||
|
||||
if-eqz v$free1, :unfiltered
|
||||
@@ -141,7 +163,7 @@ class LithoFilterPatch : BytecodePatch(
|
||||
}
|
||||
|
||||
// endregion
|
||||
} ?: throw ComponentContextParserFingerprint.exception
|
||||
} ?: return ComponentContextParserFingerprint.toErrorResult()
|
||||
|
||||
LithoFilterFingerprint.result?.mutableMethod?.apply {
|
||||
removeInstructions(2, 4) // Remove dummy filter.
|
||||
@@ -157,7 +179,9 @@ class LithoFilterPatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw LithoFilterFingerprint.exception
|
||||
} ?: return LithoFilterFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
override fun close() = LithoFilterFingerprint.result!!
|
||||
@@ -173,7 +197,9 @@ class LithoFilterPatch : BytecodePatch(
|
||||
private val Instruction.descriptor
|
||||
get() = (this as ReferenceInstruction).reference.toString()
|
||||
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/LithoFilterPatch;"
|
||||
private const val FILTER_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/LithoFilterPatch;" +
|
||||
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
|
||||
|
||||
internal lateinit var addFilter: (String) -> Unit
|
||||
private set
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.microg.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class MicroGPatchCompatibility
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.microg.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object GooglePlayUtilityFingerprint : MethodFingerprint(
|
||||
returnType = "I",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.microg.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object ServiceCheckFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
|
||||
+5
-1
@@ -4,6 +4,8 @@ import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint
|
||||
@@ -38,7 +40,7 @@ class MicroGBytecodePatch : BytecodePatch(
|
||||
WatchWhileActivityFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// apply common microG patch
|
||||
MicroGBytecodeHelper.patchBytecode(
|
||||
context, arrayOf(
|
||||
@@ -63,5 +65,7 @@ class MicroGBytecodePatch : BytecodePatch(
|
||||
|
||||
// inject the notice for MicroG
|
||||
MicroGBytecodeHelper.injectNotice(WatchWhileActivityFingerprint)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -1,6 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.microg.patch.resource
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.settings.preference.impl.Preference
|
||||
@@ -18,7 +20,7 @@ import app.revanced.util.microg.MicroGResourceHelper
|
||||
|
||||
@DependsOn([SettingsResourcePatch::class])
|
||||
class MicroGResourcePatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.addPreference(
|
||||
Preference(
|
||||
StringResource("microg_settings", "MicroG Settings"),
|
||||
@@ -45,5 +47,7 @@ class MicroGResourcePatch : ResourcePatch {
|
||||
|
||||
// add strings
|
||||
MicroGResourceHelper.addStrings(context)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.minimizedplayback.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class MinimizedPlaybackCompatibility
|
||||
+9
-18
@@ -2,33 +2,24 @@ package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("I", "L", "L"),
|
||||
parameters = listOf("I", "L", "L"),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_NE,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IF_NE,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_NE,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IF_EQ,
|
||||
Opcode.GOTO,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.RETURN_VOID
|
||||
Opcode.INVOKE_STATIC
|
||||
),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.implementation!!.instructions.any {
|
||||
((it as? NarrowLiteralInstruction)?.narrowLiteral == 5)
|
||||
}
|
||||
methodDef.definingClass.endsWith("MinimizedPlaybackPolicyController;")
|
||||
}
|
||||
)
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
|
||||
"Z",
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Class fingerprint for [MinimizedPlaybackSettingsFingerprint]
|
||||
|
||||
+13
-8
@@ -1,13 +1,16 @@
|
||||
package app.revanced.patches.youtube.misc.minimizedplayback.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
@@ -21,8 +24,8 @@ import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.Minimize
|
||||
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsParentFingerprint
|
||||
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch
|
||||
@Name("Minimized playback")
|
||||
@@ -36,7 +39,7 @@ class MinimizedPlaybackPatch : BytecodePatch(
|
||||
KidsMinimizedPlaybackPolicyControllerFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// TODO: remove this empty preference sometime after mid 2023
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
NonInteractivePreference(
|
||||
@@ -54,10 +57,10 @@ class MinimizedPlaybackPatch : BytecodePatch(
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
} ?: throw MinimizedPlaybackManagerFingerprint.exception
|
||||
} ?: return MinimizedPlaybackManagerFingerprint.toErrorResult()
|
||||
|
||||
// Enable minimized playback option in YouTube settings
|
||||
MinimizedPlaybackSettingsParentFingerprint.result ?: throw MinimizedPlaybackSettingsParentFingerprint.exception
|
||||
MinimizedPlaybackSettingsParentFingerprint.result ?: return MinimizedPlaybackSettingsParentFingerprint.toErrorResult()
|
||||
MinimizedPlaybackSettingsFingerprint.resolve(context, MinimizedPlaybackSettingsParentFingerprint.result!!.classDef)
|
||||
MinimizedPlaybackSettingsFingerprint.result?.apply {
|
||||
val booleanCalls = method.implementation!!.instructions.withIndex()
|
||||
@@ -75,7 +78,7 @@ class MinimizedPlaybackPatch : BytecodePatch(
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
} ?: throw MinimizedPlaybackSettingsFingerprint.exception
|
||||
} ?: return MinimizedPlaybackSettingsFingerprint.toErrorResult()
|
||||
|
||||
// Force allowing background play for videos labeled for kids.
|
||||
// Some regions and YouTube accounts do not require this patch.
|
||||
@@ -84,7 +87,9 @@ class MinimizedPlaybackPatch : BytecodePatch(
|
||||
0,
|
||||
"return-void"
|
||||
)
|
||||
} ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception
|
||||
} ?: return KidsMinimizedPlaybackPolicyControllerFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playercontrols.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class PlayerControlsCompatibility
|
||||
+7
-14
@@ -1,39 +1,32 @@
|
||||
package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
|
||||
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Name("Player controls bytecode patch")
|
||||
@DependsOn([BottomControlsResourcePatch::class])
|
||||
@Description("Manages the code for the player controls of the YouTube player.")
|
||||
@PlayerControlsCompatibility
|
||||
class PlayerControlsBytecodePatch : BytecodePatch(
|
||||
listOf(
|
||||
LayoutConstructorFingerprint,
|
||||
BottomControlsInflateFingerprint
|
||||
)
|
||||
listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LayoutConstructorFingerprint.result?.let {
|
||||
if (!PlayerControlsVisibilityFingerprint.resolve(context, it.classDef))
|
||||
throw LayoutConstructorFingerprint.exception
|
||||
} ?: throw LayoutConstructorFingerprint.exception
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
|
||||
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ package app.revanced.patches.youtube.misc.playercontrols.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object BottomControlsInflateFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
|
||||
|
||||
+5
-2
@@ -2,10 +2,13 @@ package app.revanced.patches.youtube.misc.playercontrols.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object PlayerControlsVisibilityFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf("Z", "Z")
|
||||
parameters = listOf("Z", "Z"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
||||
}
|
||||
)
|
||||
+6
-2
@@ -1,7 +1,9 @@
|
||||
package app.revanced.patches.youtube.misc.playercontrols.resource.patch
|
||||
|
||||
import app.revanced.patcher.util.DomFileEditor
|
||||
import app.revanced.patcher.data.DomFileEditor
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||
@@ -9,12 +11,14 @@ import java.io.Closeable
|
||||
|
||||
@DependsOn([ResourceMappingPatch::class])
|
||||
class BottomControlsResourcePatch : ResourcePatch, Closeable {
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
resourceContext = context
|
||||
targetXmlEditor = context.xmlEditor[TARGET_RESOURCE]
|
||||
|
||||
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
|
||||
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playeroverlay.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class PlayerOverlaysHookCompatibility
|
||||
|
||||
+4
-1
@@ -5,6 +5,8 @@ import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playeroverlay.annotation.PlayerOverlaysHookCompatibility
|
||||
@@ -19,12 +21,13 @@ class PlayerOverlaysHookPatch : BytecodePatch(
|
||||
PlayerOverlaysOnFinishInflateFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// hook YouTubePlayerOverlaysLayout.onFinishInflate()
|
||||
val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod
|
||||
method.addInstruction(
|
||||
method.implementation!!.instructions.size - 2,
|
||||
"invoke-static { p0 }, Lapp/revanced/integrations/patches/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V"
|
||||
)
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.playertype.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class PlayerTypeHookCompatibility
|
||||
|
||||
+21
-3
@@ -2,16 +2,34 @@ package app.revanced.patches.youtube.misc.playertype.fingerprint
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object PlayerTypeFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IF_NE,
|
||||
Opcode.RETURN_VOID,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.RETURN_VOID,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.RETURN_VOID
|
||||
),
|
||||
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;") }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;")
|
||||
}
|
||||
)
|
||||
|
||||
+6
-3
@@ -2,8 +2,8 @@ package app.revanced.patches.youtube.misc.playertype.fingerprint
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object VideoStateFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -17,5 +17,8 @@ object VideoStateFingerprint : MethodFingerprint(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_OBJECT, // obfuscated parameter field name
|
||||
)
|
||||
),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
|
||||
}
|
||||
)
|
||||
+19
-9
@@ -1,6 +1,6 @@
|
||||
package app.revanced.patches.youtube.misc.playertype.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
@@ -8,29 +8,37 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.annotation.PlayerTypeHookCompatibility
|
||||
import app.revanced.patches.youtube.misc.playertype.fingerprint.PlayerTypeFingerprint
|
||||
import app.revanced.patches.youtube.misc.playertype.fingerprint.VideoStateFingerprint
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
@Name("Player type hook")
|
||||
@Description("Hook to get the current player type and video playback state.")
|
||||
@PlayerTypeHookCompatibility
|
||||
@DependsOn([IntegrationsPatch::class])
|
||||
class PlayerTypeHookPatch : BytecodePatch(
|
||||
listOf(PlayerTypeFingerprint, VideoStateFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
PlayerTypeFingerprint.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
|
||||
) ?: throw PlayerTypeFingerprint.exception
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
|
||||
PlayerTypeFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
addInstruction(
|
||||
0,
|
||||
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
|
||||
)
|
||||
}
|
||||
} ?: return PlayerTypeFingerprint.toErrorResult()
|
||||
|
||||
VideoStateFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
@@ -39,7 +47,9 @@ class PlayerTypeHookPatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw VideoStateFingerprint.exception
|
||||
} ?: return VideoStateFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object LicenseActivityFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object SetThemeFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
+11
-7
@@ -1,6 +1,6 @@
|
||||
package app.revanced.patches.youtube.misc.settings.bytecode.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
@@ -9,6 +9,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.settings.preference.impl.Preference
|
||||
import app.revanced.patches.shared.settings.util.AbstractPreferenceScreen
|
||||
@@ -16,9 +18,9 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.LicenseActivityFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.SetThemeFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.util.MethodUtil
|
||||
import java.io.Closeable
|
||||
|
||||
@DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class])
|
||||
@@ -27,7 +29,7 @@ import java.io.Closeable
|
||||
class SettingsPatch : BytecodePatch(
|
||||
listOf(LicenseActivityFingerprint, SetThemeFingerprint)
|
||||
), Closeable {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// TODO: Remove this when it is only required at one place.
|
||||
fun getSetThemeInstructionString(
|
||||
registers: String = "v0",
|
||||
@@ -55,7 +57,7 @@ class SettingsPatch : BytecodePatch(
|
||||
addInstruction(returnIndex + 1, "return-object v0")
|
||||
}
|
||||
}
|
||||
} ?: throw SetThemeFingerprint.exception
|
||||
} ?: return SetThemeFingerprint.toErrorResult()
|
||||
|
||||
|
||||
// Modify the license activity and remove all existing layout code.
|
||||
@@ -86,6 +88,8 @@ class SettingsPatch : BytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
@@ -119,7 +123,7 @@ class SettingsPatch : BytecodePatch(
|
||||
/**
|
||||
* Preference screens patches should add their settings to.
|
||||
*/
|
||||
object PreferenceScreen : AbstractPreferenceScreen() {
|
||||
internal object PreferenceScreen : AbstractPreferenceScreen() {
|
||||
val ADS = Screen("ads", "Ads", "Ad related settings")
|
||||
val INTERACTIONS = Screen("interactions", "Interaction", "Settings related to interactions")
|
||||
val LAYOUT = Screen("layout", "Layout", "Settings related to the layout")
|
||||
|
||||
+6
-2
@@ -1,8 +1,10 @@
|
||||
package app.revanced.patches.youtube.misc.settings.resource.patch
|
||||
|
||||
import app.revanced.patcher.data.DomFileEditor
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.DomFileEditor
|
||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||
import app.revanced.patches.shared.settings.preference.addPreference
|
||||
import app.revanced.patches.shared.settings.preference.impl.*
|
||||
@@ -19,7 +21,7 @@ class SettingsResourcePatch : AbstractSettingsResourcePatch(
|
||||
"revanced_prefs",
|
||||
"settings"
|
||||
) {
|
||||
override fun execute(context: ResourceContext) {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
super.execute(context)
|
||||
|
||||
// Used for a fingerprint from SettingsPatch.
|
||||
@@ -86,6 +88,8 @@ class SettingsResourcePatch : AbstractSettingsResourcePatch(
|
||||
)
|
||||
|
||||
context.mergeStrings("settings/host/values/strings.xml")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
|
||||
|
||||
+5
-1
@@ -6,6 +6,8 @@ import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
@@ -23,7 +25,7 @@ import app.revanced.patches.youtube.misc.zoomhaptics.fingerprints.ZoomHapticsFin
|
||||
class ZoomHapticsPatch : BytecodePatch(
|
||||
listOf(ZoomHapticsFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_disable_zoom_haptics",
|
||||
@@ -45,5 +47,7 @@ class ZoomHapticsPatch : BytecodePatch(
|
||||
""",
|
||||
ExternalLabel("vibrate", zoomHapticsFingerprintMethod.getInstruction(0))
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user