From 481d33bc8797196d96fba1288d6a2e17fbaa3032 Mon Sep 17 00:00:00 2001 From: d4rkk3y Date: Sun, 17 Dec 2023 18:55:33 +0700 Subject: [PATCH 1/8] feat(Tiktok-Playback speed): remember playback speed --- .../interaction/speed/PlaybackSpeedPatch.kt | 44 ++++++++++++++++++- .../fingerprints/ChangeSpeedFingerprint.kt | 30 +++++++++++++ .../speed/fingerprints/GetSpeedFingerprint.kt | 10 +++++ .../OnRenderFirstFrameFingerprint.kt | 10 +++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 3f7c17e7b4..54c4f4d6e0 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -1,15 +1,21 @@ package app.revanced.patches.tiktok.interaction.speed import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.tiktok.interaction.speed.fingerprints.ChangeSpeedFingerprint +import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint +import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint import app.revanced.util.exception import app.revanced.util.indexOfFirstInstruction import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -22,7 +28,14 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference ] ) @Suppress("unused") -object PlaybackSpeedPatch : BytecodePatch(setOf(SpeedControlParentFingerprint)) { +object PlaybackSpeedPatch : BytecodePatch( + setOf( + SpeedControlParentFingerprint, + GetSpeedFingerprint, + OnRenderFirstFrameFingerprint, + ChangeSpeedFingerprint + ) +) { override fun execute(context: BytecodeContext) { SpeedControlParentFingerprint.result?.mutableMethod?.apply { val targetMethodCallIndex = indexOfFirstInstruction { @@ -45,5 +58,34 @@ object PlaybackSpeedPatch : BytecodePatch(setOf(SpeedControlParentFingerprint)) """ ) } ?: throw SpeedControlParentFingerprint.exception + + GetSpeedFingerprint.result?.mutableMethod?.apply { + val injectIndex = indexOfFirstInstruction { + opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType == "F" + } + 2 + val reg = (getInstruction(injectIndex - 1) as Instruction11x).registerA + addInstruction( + injectIndex, + "invoke-static { v$reg }, Lapp/revanced/tiktok/speed/SpeedPatch;->saveDefaultSpeed(F)V" + ) + } ?: throw GetSpeedFingerprint.exception + + OnRenderFirstFrameFingerprint.result?.mutableMethod?.apply { + ChangeSpeedFingerprint.result?.mutableMethod?.let { changeSpeedMethod -> + addInstructions( + 0, + """ + const/4 v0, 0x1 + invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; + move-result-object v0 + invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; + move-result-object v1 + invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getDefaultSpeed()F + move-result-object v2 + invoke-static { v0, v1, v2 }, ${changeSpeedMethod.definingClass}->${changeSpeedMethod.name}(${changeSpeedMethod.parameterTypes[0]}${changeSpeedMethod.parameterTypes[1]}${changeSpeedMethod.parameterTypes[2]})V + """ + ) + } ?: throw ChangeSpeedFingerprint.exception + } ?: throw OnRenderFirstFrameFingerprint.exception } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt new file mode 100644 index 0000000000..dca4a3a471 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt @@ -0,0 +1,30 @@ +package app.revanced.patches.tiktok.interaction.speed.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object ChangeSpeedFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf( + "Ljava/lang/String;", + "Lcom/ss/android/ugc/aweme/feed/model/Aweme;", + "F" + ), + opcodes = listOf( + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.SGET, + Opcode.SPUT_OBJECT, + Opcode.SPUT, + Opcode.SPUT, + Opcode.SGET_OBJECT, + Opcode.IF_EQZ, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT + ), + strings = listOf("enterFrom") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt new file mode 100644 index 0000000000..58a6239d42 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.tiktok.interaction.speed.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object GetSpeedFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && + methodDef.name == "onFeedSpeedSelectedEvent" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt new file mode 100644 index 0000000000..4b517026a3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.tiktok.interaction.speed.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object OnRenderFirstFrameFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && + methodDef.name == "onRenderFirstFrame" + } +) \ No newline at end of file From a9f874dab676c61b3b197c48d2780b7bb8b61e31 Mon Sep 17 00:00:00 2001 From: d4rkk3y Date: Sun, 17 Dec 2023 22:08:24 +0700 Subject: [PATCH 2/8] chore(Tiktok-Playback speed): update patch description. --- .../patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 54c4f4d6e0..0d76f01bdd 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -21,7 +21,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Playback speed", - description = "Enables the playback speed option for all videos.", + description = "Enables the playback speed option for all videos and retains the speed configurations in between videos.", compatiblePackages = [ CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) From eb7447dae75d291119448b0db50049e79d15e050 Mon Sep 17 00:00:00 2001 From: d4rkk3y Date: Sun, 17 Dec 2023 23:18:44 +0700 Subject: [PATCH 3/8] refactor(Tiktok-Share): share fingerprints --- .../patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt | 2 +- .../fingerprints/OnRenderFirstFrameFingerprint.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/kotlin/app/revanced/patches/tiktok/{interaction/speed => share}/fingerprints/OnRenderFirstFrameFingerprint.kt (81%) diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 0d76f01bdd..52e11b9834 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -10,7 +10,7 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.tiktok.interaction.speed.fingerprints.ChangeSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint -import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint +import app.revanced.patches.tiktok.share.fingerprints.OnRenderFirstFrameFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint import app.revanced.util.exception import app.revanced.util.indexOfFirstInstruction diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt rename to src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt index 4b517026a3..016a047e7e 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.tiktok.interaction.speed.fingerprints +package app.revanced.patches.tiktok.share.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint From 74868cfdc9e70337494f8a312bf723994db7668b Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 17 Dec 2023 20:31:28 +0100 Subject: [PATCH 4/8] refactor: Simplify code --- .../interaction/speed/PlaybackSpeedPatch.kt | 70 +++++++++---------- .../speed/fingerprints/GetSpeedFingerprint.kt | 3 +- .../OnRenderFirstFrameFingerprint.kt | 7 +- 3 files changed, 38 insertions(+), 42 deletions(-) rename src/main/kotlin/app/revanced/patches/tiktok/{share => interaction/speed}/fingerprints/OnRenderFirstFrameFingerprint.kt (66%) diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 52e11b9834..e012aa494b 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -10,18 +10,18 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.tiktok.interaction.speed.fingerprints.ChangeSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint -import app.revanced.patches.tiktok.share.fingerprints.OnRenderFirstFrameFingerprint +import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint import app.revanced.util.exception +import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Playback speed", - description = "Enables the playback speed option for all videos and retains the speed configurations in between videos.", + description = "Enables the playback speed option for all videos and " + + "retains the speed configurations in between videos.", compatiblePackages = [ CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) @@ -37,20 +37,20 @@ object PlaybackSpeedPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext) { - SpeedControlParentFingerprint.result?.mutableMethod?.apply { - val targetMethodCallIndex = indexOfFirstInstruction { - if (opcode == Opcode.INVOKE_STATIC) { - val paramsTypes = ((this as Instruction35c).reference as MethodReference).parameterTypes - paramsTypes.size == 1 && paramsTypes[0].contains("/Aweme;") - } else false + SpeedControlParentFingerprint.result?.mutableMethod?.let { it -> + val speedControlMethodCallIndex = it.indexOfFirstInstruction { + val paramsTypes = getReference()?.parameterTypes + ?: return@indexOfFirstInstruction false + + paramsTypes.size == 1 && paramsTypes.first().contains("/Aweme;") } - val isSpeedEnableMethod = context - .toMethodWalker(this) - .nextMethod(targetMethodCallIndex, true) + val enableSpeedControlMethod = context + .toMethodWalker(it) + .nextMethod(speedControlMethodCallIndex, true) .getMethod() as MutableMethod - isSpeedEnableMethod.addInstructions( + enableSpeedControlMethod.addInstructions( 0, """ const/4 v0, 0x1 @@ -60,32 +60,30 @@ object PlaybackSpeedPatch : BytecodePatch( } ?: throw SpeedControlParentFingerprint.exception GetSpeedFingerprint.result?.mutableMethod?.apply { - val injectIndex = indexOfFirstInstruction { - opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType == "F" - } + 2 - val reg = (getInstruction(injectIndex - 1) as Instruction11x).registerA + val injectIndex = indexOfFirstInstruction { getReference()?.returnType == "F" } + 2 + val register = getInstruction(injectIndex - 1).registerA + addInstruction( injectIndex, - "invoke-static { v$reg }, Lapp/revanced/tiktok/speed/SpeedPatch;->saveDefaultSpeed(F)V" + "invoke-static { v$register }," + + " Lapp/revanced/tiktok/speed/SpeedPatch;->saveDefaultSpeed(F)V" ) } ?: throw GetSpeedFingerprint.exception - OnRenderFirstFrameFingerprint.result?.mutableMethod?.apply { - ChangeSpeedFingerprint.result?.mutableMethod?.let { changeSpeedMethod -> - addInstructions( - 0, - """ - const/4 v0, 0x1 - invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; - move-result-object v0 - invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; - move-result-object v1 - invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getDefaultSpeed()F - move-result-object v2 - invoke-static { v0, v1, v2 }, ${changeSpeedMethod.definingClass}->${changeSpeedMethod.name}(${changeSpeedMethod.parameterTypes[0]}${changeSpeedMethod.parameterTypes[1]}${changeSpeedMethod.parameterTypes[2]})V - """ - ) - } ?: throw ChangeSpeedFingerprint.exception - } ?: throw OnRenderFirstFrameFingerprint.exception + val changeSpeedMethod = ChangeSpeedFingerprint.result?.mutableMethod + ?: throw ChangeSpeedFingerprint.exception + OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( + 0, + """ + const/4 v0, 0x1 + invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; + move-result-object v0 + invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; + move-result-object v1 + invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getDefaultSpeed()F + move-result-object v2 + invoke-static { v0, v1, v2 }, $changeSpeedMethod + """ + ) ?: throw OnRenderFirstFrameFingerprint.exception } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt index 58a6239d42..f9845d4dc7 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/GetSpeedFingerprint.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.fingerprint.MethodFingerprint internal object GetSpeedFingerprint : MethodFingerprint( customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && - methodDef.name == "onFeedSpeedSelectedEvent" + methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onFeedSpeedSelectedEvent" } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt similarity index 66% rename from src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt rename to src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt index 016a047e7e..59f930efea 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/share/fingerprints/OnRenderFirstFrameFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnRenderFirstFrameFingerprint.kt @@ -1,10 +1,9 @@ -package app.revanced.patches.tiktok.share.fingerprints +package app.revanced.patches.tiktok.interaction.speed.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint internal object OnRenderFirstFrameFingerprint : MethodFingerprint( customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && - methodDef.name == "onRenderFirstFrame" + methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame" } -) \ No newline at end of file +) From 3afd24f4dc99eca376ef5f2834534757e45fdb59 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 17 Dec 2023 20:34:02 +0100 Subject: [PATCH 5/8] refactor --- .../patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index e012aa494b..d8986d3036 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -74,7 +74,7 @@ object PlaybackSpeedPatch : BytecodePatch( ?: throw ChangeSpeedFingerprint.exception OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( 0, - """ + """ const/4 v0, 0x1 invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; move-result-object v0 From 145eeb95fa4a8367df21208a628cd71f8c009daa Mon Sep 17 00:00:00 2001 From: d4rkk3y Date: Mon, 18 Dec 2023 05:34:38 +0700 Subject: [PATCH 6/8] fix: remove unnecessary fingerprint and add comments. --- .../interaction/speed/PlaybackSpeedPatch.kt | 45 +++++++++---------- .../fingerprints/ChangeSpeedFingerprint.kt | 13 ------ .../SpeedControlParentFingerprint.kt | 13 ------ 3 files changed, 22 insertions(+), 49 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index d8986d3036..459f5996b6 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -7,11 +7,9 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.tiktok.interaction.speed.fingerprints.ChangeSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint -import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -30,35 +28,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Suppress("unused") object PlaybackSpeedPatch : BytecodePatch( setOf( - SpeedControlParentFingerprint, GetSpeedFingerprint, OnRenderFirstFrameFingerprint, ChangeSpeedFingerprint ) ) { override fun execute(context: BytecodeContext) { - SpeedControlParentFingerprint.result?.mutableMethod?.let { it -> - val speedControlMethodCallIndex = it.indexOfFirstInstruction { - val paramsTypes = getReference()?.parameterTypes - ?: return@indexOfFirstInstruction false + val changeSpeedMethod = ChangeSpeedFingerprint.result?.mutableMethod + ?: throw ChangeSpeedFingerprint.exception - paramsTypes.size == 1 && paramsTypes.first().contains("/Aweme;") + // Enables playback speed option for all videos. + val enableSpeedControlMethod = + context.findClass(changeSpeedMethod.definingClass)?.mutableClass?.methods?.first { + it.returnType == "Z" } - - val enableSpeedControlMethod = context - .toMethodWalker(it) - .nextMethod(speedControlMethodCallIndex, true) - .getMethod() as MutableMethod - - enableSpeedControlMethod.addInstructions( - 0, - """ + enableSpeedControlMethod?.addInstructions( + 0, + """ const/4 v0, 0x1 return v0 """ - ) - } ?: throw SpeedControlParentFingerprint.exception + ) + // Catches the playback speed changed event at current video and saves it to apply to other videos. GetSpeedFingerprint.result?.mutableMethod?.apply { val injectIndex = indexOfFirstInstruction { getReference()?.returnType == "F" } + 2 val register = getInstruction(injectIndex - 1).registerA @@ -66,21 +58,28 @@ object PlaybackSpeedPatch : BytecodePatch( addInstruction( injectIndex, "invoke-static { v$register }," + - " Lapp/revanced/tiktok/speed/SpeedPatch;->saveDefaultSpeed(F)V" + " Lapp/revanced/tiktok/speed/SpeedPatch;->rememberPlaybackSpeed(F)V" ) } ?: throw GetSpeedFingerprint.exception - val changeSpeedMethod = ChangeSpeedFingerprint.result?.mutableMethod - ?: throw ChangeSpeedFingerprint.exception + // Changes current video playback speed at the first frame of video using the saved playback speed. + // Because the default behavior of the TikTok app is that playback speed will reset to 1.0 + // when swiping to the next video. OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( 0, """ + # The changeSpeedMethod have 3 arguments. + # First argument is a String. It changed depend on where video playing such as home page, following page, search result page, ... + # We are able to get it use getEnterFrom method. const/4 v0, 0x1 invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; move-result-object v0 + # Second argument is a Aweme. It is some kind of data for a TikTok video. + # We can get it use getCurrentAweme method. invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; move-result-object v1 - invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getDefaultSpeed()F + # Third argument is a float. It is the playback speed value to apply to the TikTok video. + invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getPlaybackSpeed()F move-result-object v2 invoke-static { v0, v1, v2 }, $changeSpeedMethod """ diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt index dca4a3a471..fe9fad47a9 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt @@ -13,18 +13,5 @@ internal object ChangeSpeedFingerprint : MethodFingerprint( "Lcom/ss/android/ugc/aweme/feed/model/Aweme;", "F" ), - opcodes = listOf( - Opcode.CONST_STRING, - Opcode.INVOKE_STATIC, - Opcode.SGET, - Opcode.SPUT_OBJECT, - Opcode.SPUT, - Opcode.SPUT, - Opcode.SGET_OBJECT, - Opcode.IF_EQZ, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.SGET_OBJECT - ), strings = listOf("enterFrom") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt deleted file mode 100644 index 7edae32e14..0000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.interaction.speed.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object SpeedControlParentFingerprint : MethodFingerprint( - strings = listOf( - "onStopTrackingTouch, hasTouchMove=", - ", isCurVideoPaused: ", - "already_shown_edge_speed_guide" - ) -) \ No newline at end of file From ce5f658c0f20f36bc4aee051b1cba3d6c8debbdc Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 2 Jan 2024 17:34:25 +0100 Subject: [PATCH 7/8] improve readability and semantics --- .../AbstractTransformInstructionsPatch.kt | 1 - .../interaction/speed/PlaybackSpeedPatch.kt | 80 +++++++++---------- ...erprint.kt => OnVideoSwipedFingerprint.kt} | 3 +- 3 files changed, 38 insertions(+), 46 deletions(-) rename src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/{ChangeSpeedFingerprint.kt => OnVideoSwipedFingerprint.kt} (81%) diff --git a/src/main/kotlin/app/revanced/patches/all/misc/transformation/AbstractTransformInstructionsPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/transformation/AbstractTransformInstructionsPatch.kt index 71699f1983..a4c447e9dc 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/transformation/AbstractTransformInstructionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/transformation/AbstractTransformInstructionsPatch.kt @@ -10,7 +10,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction @Suppress("MemberVisibilityCanBePrivate") abstract class AbstractTransformInstructionsPatch : BytecodePatch() { - abstract fun filterMap( classDef: ClassDef, method: Method, diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 459f5996b6..6e5887432a 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -5,11 +5,12 @@ 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.PatchException import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.tiktok.interaction.speed.fingerprints.ChangeSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint +import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnVideoSwipedFingerprint import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -30,59 +31,52 @@ object PlaybackSpeedPatch : BytecodePatch( setOf( GetSpeedFingerprint, OnRenderFirstFrameFingerprint, - ChangeSpeedFingerprint + OnVideoSwipedFingerprint ) ) { override fun execute(context: BytecodeContext) { - val changeSpeedMethod = ChangeSpeedFingerprint.result?.mutableMethod - ?: throw ChangeSpeedFingerprint.exception + OnVideoSwipedFingerprint.result?.let { onVideoSwiped -> + // Remember the playback speed of the current video. + GetSpeedFingerprint.result?.mutableMethod?.apply { + val injectIndex = indexOfFirstInstruction { getReference()?.returnType == "F" } + 2 + val register = getInstruction(injectIndex - 1).registerA - // Enables playback speed option for all videos. - val enableSpeedControlMethod = - context.findClass(changeSpeedMethod.definingClass)?.mutableClass?.methods?.first { - it.returnType == "Z" - } - enableSpeedControlMethod?.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - // Catches the playback speed changed event at current video and saves it to apply to other videos. - GetSpeedFingerprint.result?.mutableMethod?.apply { - val injectIndex = indexOfFirstInstruction { getReference()?.returnType == "F" } + 2 - val register = getInstruction(injectIndex - 1).registerA + addInstruction( + injectIndex, + "invoke-static { v$register }," + + " Lapp/revanced/tiktok/speed/SpeedPatch;->rememberPlaybackSpeed(F)V" + ) + } ?: throw GetSpeedFingerprint.exception - addInstruction( - injectIndex, - "invoke-static { v$register }," + - " Lapp/revanced/tiktok/speed/SpeedPatch;->rememberPlaybackSpeed(F)V" - ) - } ?: throw GetSpeedFingerprint.exception - - // Changes current video playback speed at the first frame of video using the saved playback speed. - // Because the default behavior of the TikTok app is that playback speed will reset to 1.0 - // when swiping to the next video. - OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( - 0, - """ - # The changeSpeedMethod have 3 arguments. - # First argument is a String. It changed depend on where video playing such as home page, following page, search result page, ... - # We are able to get it use getEnterFrom method. + // By default, the playback speed will reset to 1.0 at the start of each video. + // Instead, override it with the desired playback speed. + OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( + 0, + """ + # Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method. const/4 v0, 0x1 invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; move-result-object v0 - # Second argument is a Aweme. It is some kind of data for a TikTok video. - # We can get it use getCurrentAweme method. + + # Model of current video retrieved using getCurrentAweme method. invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; move-result-object v1 - # Third argument is a float. It is the playback speed value to apply to the TikTok video. + + # Desired playback speed retrieved using getPlaybackSpeed method. invoke-static {}, Lapp/revanced/tiktok/speed/SpeedPatch;->getPlaybackSpeed()F move-result-object v2 - invoke-static { v0, v1, v2 }, $changeSpeedMethod + invoke-static { v0, v1, v2 }, ${onVideoSwiped.method} + """ + ) ?: throw OnRenderFirstFrameFingerprint.exception + + // Force enable the playback speed option for all videos. + onVideoSwiped.mutableClass.methods.find { method -> method.returnType == "Z" }?.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 """ - ) ?: throw OnRenderFirstFrameFingerprint.exception + ) ?: throw PatchException("Failed to force enable the playback speed option.") + } ?: throw OnVideoSwipedFingerprint.exception } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt rename to src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt index fe9fad47a9..b1e68bb80a 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/ChangeSpeedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt @@ -3,9 +3,8 @@ package app.revanced.patches.tiktok.interaction.speed.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -internal object ChangeSpeedFingerprint : MethodFingerprint( +internal object OnVideoSwipedFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf( From 801530a1b105011daf28cee2198ff0e08b3770c1 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 9 Jan 2024 20:09:31 +0100 Subject: [PATCH 8/8] use correct name --- .../tiktok/interaction/speed/PlaybackSpeedPatch.kt | 8 ++++---- ...OnVideoSwipedFingerprint.kt => SetSpeedFingerprint.kt} | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/{OnVideoSwipedFingerprint.kt => SetSpeedFingerprint.kt} (88%) diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt index 6e5887432a..6a73e60fcf 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/PlaybackSpeedPatch.kt @@ -10,7 +10,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint -import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnVideoSwipedFingerprint +import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -31,11 +31,11 @@ object PlaybackSpeedPatch : BytecodePatch( setOf( GetSpeedFingerprint, OnRenderFirstFrameFingerprint, - OnVideoSwipedFingerprint + SetSpeedFingerprint ) ) { override fun execute(context: BytecodeContext) { - OnVideoSwipedFingerprint.result?.let { onVideoSwiped -> + SetSpeedFingerprint.result?.let { onVideoSwiped -> // Remember the playback speed of the current video. GetSpeedFingerprint.result?.mutableMethod?.apply { val injectIndex = indexOfFirstInstruction { getReference()?.returnType == "F" } + 2 @@ -77,6 +77,6 @@ object PlaybackSpeedPatch : BytecodePatch( return v0 """ ) ?: throw PatchException("Failed to force enable the playback speed option.") - } ?: throw OnVideoSwipedFingerprint.exception + } ?: throw SetSpeedFingerprint.exception } } diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SetSpeedFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt rename to src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SetSpeedFingerprint.kt index b1e68bb80a..97e566b97a 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/OnVideoSwipedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SetSpeedFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal object OnVideoSwipedFingerprint : MethodFingerprint( +internal object SetSpeedFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf( @@ -13,4 +13,4 @@ internal object OnVideoSwipedFingerprint : MethodFingerprint( "F" ), strings = listOf("enterFrom") -) \ No newline at end of file +)