From 30f5cb50e42c5979945e3c419071682021de3742 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 12 Jun 2024 23:09:32 +0900 Subject: [PATCH] feat(YouTube/Swipe controls) add `Enable swipe to change video` setting (YouTube 19.19.39+) --- .../swipe/controls/SwipeControlsPatch.kt | 114 +++++++++--------- .../SwipeToSwitchVideoFingerprint.kt | 11 ++ .../WatchPanelGesturesFingerprint.kt | 3 + .../youtube/settings/host/values/strings.xml | 3 + .../youtube/settings/xml/revanced_prefs.xml | 3 + 5 files changed, 76 insertions(+), 58 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeToSwitchVideoFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt index 366b3f7c2..411199c33 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt @@ -2,13 +2,13 @@ package app.revanced.patches.youtube.swipe.controls 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.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.swipe.controls.fingerprints.FullScreenEngagementOverlayFingerprint import app.revanced.patches.youtube.swipe.controls.fingerprints.HDRBrightnessFingerprint +import app.revanced.patches.youtube.swipe.controls.fingerprints.SwipeToSwitchVideoFingerprint import app.revanced.patches.youtube.swipe.controls.fingerprints.WatchPanelGesturesFingerprint import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.INTEGRATIONS_PATH @@ -23,14 +23,13 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts import app.revanced.util.ResourceGroup import app.revanced.util.copyResources -import app.revanced.util.getTargetIndex import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import app.revanced.util.transformMethods import app.revanced.util.traverseClassHierarchy import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.immutable.ImmutableMethod @@ -49,6 +48,7 @@ object SwipeControlsPatch : BaseBytecodePatch( fingerprints = setOf( FullScreenEngagementOverlayFingerprint, HDRBrightnessFingerprint, + SwipeToSwitchVideoFingerprint, WatchPanelGesturesFingerprint ) ) { @@ -101,74 +101,63 @@ object SwipeControlsPatch : BaseBytecodePatch( // endregion + var settingArray = arrayOf( + "PREFERENCE_SCREEN: SWIPE_CONTROLS" + ) + // region patch for disable HDR auto brightness - HDRBrightnessFingerprint.result?.let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->disableHDRAutoBrightness()Z - move-result v0 - if-eqz v0, :default - return-void - """, ExternalLabel("default", getInstruction(0)) - ) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS", - "SETTINGS: DISABLE_HDR_BRIGHTNESS" - ) + // Since it does not support all versions, + // add settings only if the patch is successful. + HDRBrightnessFingerprint.result?.mutableMethod?.apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->disableHDRAutoBrightness()Z + move-result v0 + if-eqz v0, :default + return-void + """, ExternalLabel("default", getInstruction(0)) ) - } // no exceptions are raised for compatibility with all versions. + + settingArray += "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS" + settingArray += "SETTINGS: DISABLE_HDR_BRIGHTNESS" + } + + // endregion + + // region patch for enable swipe to switch video + + // Since it does not support all versions, + // add settings only if the patch is successful. + SwipeToSwitchVideoFingerprint.result?.let { + SwipeToSwitchVideoFingerprint.literalInstructionBooleanHook( + 45631116, + "$INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableSwipeToSwitchVideo()Z" + ) + + settingArray += "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS" + settingArray += "SETTINGS: ENABLE_SWIPE_TO_SWITCH_VIDEO" + } // endregion // region patch for enable watch panel gestures - // Even if it fails to resolve the fingerprint, the [Swipe controls] patch should succeed. - // So instead of throwing an exception, it just prints WARNING. + // Since it does not support all versions, + // add settings only if the patch is successful. WatchPanelGesturesFingerprint.result?.let { - it.mutableMethod.apply { - val literalIndex = getWideLiteralInstructionIndex(45372793) - val targetIndex = getTargetIndex(literalIndex, Opcode.MOVE_RESULT) - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {}, $INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableWatchPanelGestures()Z - move-result v$targetRegister - """ - ) - } - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS", - "SETTINGS: ENABLE_WATCH_PANEL_GESTURES" - ) + WatchPanelGesturesFingerprint.literalInstructionBooleanHook( + 45372793, + "$INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableWatchPanelGestures()Z" ) - } ?: println("WARNING: Failed to resolve WatchPanelGesturesFingerprint") + + settingArray += "PREFERENCE_CATEGORY: SWIPE_CONTROLS_EXPERIMENTAL_FLAGS" + settingArray += "SETTINGS: ENABLE_WATCH_PANEL_GESTURES" + } // endregion - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE_SCREEN: SWIPE_CONTROLS" - ) - ) - - SettingsPatch.updatePatchStatus(this) + // region copy resources contexts.copyResources( "youtube/swipecontrols", @@ -180,5 +169,14 @@ object SwipeControlsPatch : BaseBytecodePatch( "ic_sc_volume_normal.xml" ) ) + + // endregion + + /** + * Add settings + */ + SettingsPatch.addPreference(settingArray) + + SettingsPatch.updatePatchStatus(this) } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeToSwitchVideoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeToSwitchVideoFingerprint.kt new file mode 100644 index 000000000..8ad8fb9e3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/SwipeToSwitchVideoFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.swipe.controls.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +/** + * This fingerprint is compatible with YouTube v19.19.39+ + */ +internal object SwipeToSwitchVideoFingerprint : LiteralValueFingerprint( + returnType = "V", + literalSupplier = { 45631116 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt index 51241db21..e5dddb715 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/fingerprints/WatchPanelGesturesFingerprint.kt @@ -2,6 +2,9 @@ package app.revanced.patches.youtube.swipe.controls.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint +/** + * This fingerprint is compatible with YouTube v18.29.38+ + */ internal object WatchPanelGesturesFingerprint : LiteralValueFingerprint( returnType = "V", literalSupplier = { 45372793 } diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index e0fe19f50..30264fd37 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -1111,6 +1111,9 @@ Limitation: Official headers in search results will be hidden." Enable watch panel gestures Entering fullscreen when swiping down below the video player is enabled. Entering fullscreen when swiping down below the video player is disabled. + Enable swipe to change video + Swiping up / down will play the next / previous video. + Swiping up / down will not play the next / previous video. Auto diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 87f8f9572..b6e29762e 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -504,6 +504,9 @@ + +