-
-
Notifications
You must be signed in to change notification settings - Fork 430
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(youtube): support version
18.19.35
- Loading branch information
Showing
74 changed files
with
349 additions
and
304 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
...es/youtube/interaction/seekbar/fingerprints/AccessibilityPlayerProgressTimeFingerprint.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints | ||
|
||
import app.revanced.patcher.extensions.or | ||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint | ||
import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch | ||
import org.jf.dexlib2.AccessFlags | ||
import org.jf.dexlib2.Opcode | ||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction | ||
|
||
|
||
object AccessibilityPlayerProgressTimeFingerprint : MethodFingerprint( | ||
returnType = "L", | ||
access = AccessFlags.PUBLIC or AccessFlags.FINAL, | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.implementation?.instructions?.any { instruction -> | ||
if (instruction.opcode != Opcode.CONST) return@any false | ||
|
||
val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral | ||
|
||
EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime == wideLiteral | ||
} ?: false | ||
} | ||
) |
46 changes: 23 additions & 23 deletions
46
...pp/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingFingerprint.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,34 @@ | ||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints | ||
|
||
import app.revanced.patcher.extensions.or | ||
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod | ||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint | ||
import org.jf.dexlib2.AccessFlags | ||
import org.jf.dexlib2.Opcode | ||
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction | ||
|
||
|
||
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. | ||
object SeekbarTappingFingerprint : MethodFingerprint( | ||
"Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( | ||
Opcode.INVOKE_VIRTUAL, | ||
Opcode.MOVE_RESULT_WIDE, | ||
Opcode.IGET, | ||
Opcode.IGET_OBJECT, | ||
Opcode.IGET, | ||
Opcode.DIV_INT_2ADDR, | ||
Opcode.ADD_INT, | ||
Opcode.SUB_INT_2ADDR, | ||
Opcode.INT_TO_FLOAT, | ||
Opcode.CMPG_FLOAT, | ||
Opcode.IF_GTZ, | ||
Opcode.INT_TO_FLOAT, | ||
Opcode.CMPG_FLOAT, | ||
Opcode.IF_GTZ, | ||
Opcode.CONST_4, | ||
Opcode.INVOKE_INTERFACE, | ||
Opcode.NEW_INSTANCE, | ||
Opcode.INVOKE_DIRECT, | ||
returnType = "Z", | ||
access = AccessFlags.PUBLIC or AccessFlags.FINAL, | ||
parameters = listOf("L"), | ||
opcodes = listOf( | ||
Opcode.IPUT_OBJECT, | ||
Opcode.INVOKE_VIRTUAL | ||
) | ||
Opcode.INVOKE_VIRTUAL, | ||
// Insert seekbar tapping instructions here. | ||
Opcode.RETURN, | ||
Opcode.INVOKE_VIRTUAL, | ||
), | ||
customFingerprint = custom@{ methodDef, _ -> | ||
if (methodDef.name != "onTouchEvent") return@custom false | ||
|
||
methodDef.implementation!!.instructions.any { instruction -> | ||
if (instruction.opcode != Opcode.CONST) return@any false | ||
|
||
val literal = (instruction as NarrowLiteralInstruction).narrowLiteral | ||
|
||
// onTouchEvent method contains a CONST instruction | ||
// with this literal making it unique with the rest of the properties of this fingerprint. | ||
literal == Integer.MAX_VALUE | ||
} | ||
} | ||
) |
44 changes: 0 additions & 44 deletions
44
...anced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingParentFingerprint.kt
This file was deleted.
Oops, something went wrong.
144 changes: 65 additions & 79 deletions
144
...otlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,109 +1,95 @@ | ||
package app.revanced.patches.youtube.interaction.seekbar.patch | ||
|
||
import app.revanced.extensions.toErrorResult | ||
import app.revanced.patcher.annotation.Description | ||
import app.revanced.patcher.annotation.Name | ||
import app.revanced.patcher.annotation.Version | ||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.addInstructions | ||
import app.revanced.patcher.extensions.instruction | ||
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.patcher.patch.annotations.DependsOn | ||
import app.revanced.patcher.patch.annotations.Patch | ||
import app.revanced.patcher.util.smali.ExternalLabel | ||
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility | ||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.AccessibilityPlayerProgressTimeFingerprint | ||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint | ||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingParentFingerprint | ||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch | ||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch | ||
import app.revanced.patches.shared.settings.preference.impl.StringResource | ||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference | ||
import org.jf.dexlib2.Opcode | ||
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t | ||
import org.jf.dexlib2.iface.Method | ||
import org.jf.dexlib2.iface.instruction.formats.Instruction11n | ||
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction | ||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c | ||
|
||
@Patch | ||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) | ||
@DependsOn([IntegrationsPatch::class, EnableSeekbarTappingResourcePatch::class]) | ||
@Name("seekbar-tapping") | ||
@Description("Enables tap-to-seek on the seekbar of the video player.") | ||
@SeekbarTappingCompatibility | ||
@Version("0.0.1") | ||
class EnableSeekbarTappingPatch : BytecodePatch( | ||
listOf( | ||
SeekbarTappingParentFingerprint, SeekbarTappingFingerprint | ||
) | ||
listOf(AccessibilityPlayerProgressTimeFingerprint, SeekbarTappingFingerprint) | ||
) { | ||
override fun execute(context: BytecodeContext): PatchResult { | ||
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( | ||
SwitchPreference( | ||
"revanced_tap_seeking", | ||
StringResource("revanced_tap_seeking_title", "Enable seekbar tapping"), | ||
StringResource("revanced_tap_seeking_summary_on", "Seekbar tapping is enabled"), | ||
StringResource("revanced_tap_seeking_summary_off", "Seekbar tapping is disabled") | ||
) | ||
) | ||
// Find the required methods to tap the seekbar. | ||
val seekbarTappingMethods = | ||
AccessibilityPlayerProgressTimeFingerprint.result?.classDef?.methods?.let { methods -> | ||
buildMap { | ||
// find the methods which tap the seekbar | ||
methods.forEach { method -> | ||
if (method.implementation == null) return@forEach | ||
|
||
val instructions = method.implementation!!.instructions | ||
|
||
// The method has more than 7 instructions. | ||
if (instructions.count() < 7) return@forEach | ||
|
||
// The 7th instruction has the opcode CONST_4. | ||
val instruction = instructions.elementAt(6) | ||
if (instruction.opcode != Opcode.CONST_4) return@forEach | ||
|
||
// the literal for this instruction has to be either 1 or 2. | ||
val literal = (instruction as NarrowLiteralInstruction).narrowLiteral | ||
|
||
// Based on the literal, determine which method is which. | ||
if (literal == 1) this["P"] = method | ||
if (literal == 2) this["O"] = method | ||
} | ||
} | ||
} | ||
|
||
seekbarTappingMethods ?: return AccessibilityPlayerProgressTimeFingerprint.toErrorResult() | ||
|
||
SeekbarTappingFingerprint.result?.let { | ||
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1 | ||
|
||
it.mutableMethod.apply { | ||
val thisInstanceRegister = instruction<Instruction35c>(insertIndex - 1).registerC | ||
|
||
val freeRegister = 0 | ||
val xAxisRegister = 2 | ||
|
||
val pMethod = seekbarTappingMethods["P"]!! | ||
val oMethod = seekbarTappingMethods["O"]!! | ||
|
||
fun Method.toInvokeInstructionString() = | ||
"invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $definingClass->$name(I)V" | ||
|
||
addInstructions( | ||
insertIndex, | ||
""" | ||
invoke-static { }, Lapp/revanced/integrations/patches/SeekbarTappingPatch;->seekbarTappingEnabled()Z | ||
move-result v$freeRegister | ||
if-eqz v$freeRegister, :disabled | ||
${oMethod.toInvokeInstructionString()} | ||
${pMethod.toInvokeInstructionString()} | ||
""", | ||
listOf(ExternalLabel("disabled", instruction(insertIndex))) | ||
) | ||
} | ||
} ?: return SeekbarTappingFingerprint.toErrorResult() | ||
|
||
var result = SeekbarTappingParentFingerprint.result!! | ||
|
||
val tapSeekMethods = mutableMapOf<String, Method>() | ||
|
||
// find the methods which tap the seekbar | ||
for (it in result.classDef.methods) { | ||
if (it.implementation == null) continue | ||
|
||
val instructions = it.implementation!!.instructions | ||
// here we make sure we actually find the method because it has more than 7 instructions | ||
if (instructions.count() < 7) continue | ||
|
||
// we know that the 7th instruction has the opcode CONST_4 | ||
val instruction = instructions.elementAt(6) | ||
if (instruction.opcode != Opcode.CONST_4) continue | ||
|
||
// the literal for this instruction has to be either 1 or 2 | ||
val literal = (instruction as Instruction11n).narrowLiteral | ||
|
||
// method founds | ||
if (literal == 1) tapSeekMethods["P"] = it | ||
if (literal == 2) tapSeekMethods["O"] = it | ||
} | ||
|
||
// replace map because we don't need the upper one anymore | ||
result = SeekbarTappingFingerprint.result!! | ||
|
||
val implementation = result.mutableMethod.implementation!! | ||
|
||
// if tap-seeking is enabled, do not invoke the two methods below | ||
val pMethod = tapSeekMethods["P"]!! | ||
val oMethod = tapSeekMethods["O"]!! | ||
|
||
val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1 | ||
|
||
// get the required register | ||
val instruction = implementation.instructions[insertIndex - 1] | ||
if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return PatchResultError("Could not find the correct register") | ||
val register = (instruction as Instruction35c).registerC | ||
|
||
val elseLabel = implementation.newLabelForIndex(insertIndex) | ||
// the instructions are written in reverse order. | ||
result.mutableMethod.addInstructions( | ||
insertIndex, """ | ||
invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V | ||
invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V | ||
""" | ||
) | ||
|
||
// if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label | ||
implementation.addInstruction( | ||
insertIndex, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) | ||
) | ||
result.mutableMethod.addInstructions( | ||
insertIndex, """ | ||
invoke-static { }, Lapp/revanced/integrations/patches/SeekbarTappingPatch;->isTapSeekingEnabled()Z | ||
move-result v0 | ||
""" | ||
) | ||
return PatchResultSuccess() | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
...p/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingResourcePatch.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package app.revanced.patches.youtube.interaction.seekbar.patch | ||
|
||
import app.revanced.patcher.annotation.Version | ||
import app.revanced.patcher.data.ResourceContext | ||
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 | ||
import app.revanced.patches.shared.settings.preference.impl.StringResource | ||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference | ||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch | ||
|
||
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) | ||
@Version("0.0.1") | ||
class EnableSeekbarTappingResourcePatch : ResourcePatch { | ||
override fun execute(context: ResourceContext): PatchResult { | ||
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( | ||
SwitchPreference( | ||
"revanced_seekbar_tapping", | ||
StringResource("revanced_seekbar_tapping_title", "Enable seekbar tapping"), | ||
StringResource("revanced_seekbar_tapping_summary_on", "Seekbar tapping is enabled"), | ||
StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled") | ||
) | ||
) | ||
|
||
accessibilityPlayerProgressTime = ResourceMappingPatch.resourceMappings.find { | ||
it.name == "accessibility_player_progress_time" | ||
}?.id ?: return PatchResultError("Failed to find required resource") | ||
|
||
return PatchResultSuccess() | ||
} | ||
|
||
internal companion object { | ||
var accessibilityPlayerProgressTime = -1L | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
This comment was marked as spam.
Sorry, something went wrong.