From bbe79744a513c96f9016476e8435f999e94c45d7 Mon Sep 17 00:00:00 2001 From: MarcaD <152095496+MarcaDian@users.noreply.github.com> Date: Tue, 27 May 2025 10:52:01 +0300 Subject: [PATCH] feat(YouTube): Add `Disable haptic feedback` patch (#5033) --- .../patches/DisableHapticFeedbackPatch.java | 35 +++++++++ .../youtube/patches/ZoomHapticsPatch.java | 10 --- .../extension/youtube/settings/Settings.java | 5 +- patches/api/patches.api | 4 + .../DisableHapticFeedbackPatch.kt | 74 +++++++++++++++++++ .../misc/hapticfeedback/Fingerprints.kt | 23 ++++++ .../youtube/misc/zoomhaptics/Fingerprints.kt | 7 -- .../misc/zoomhaptics/ZoomHapticsPatch.kt | 51 +------------ .../resources/addresources/values/strings.xml | 21 ++++-- 9 files changed, 160 insertions(+), 70 deletions(-) create mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableHapticFeedbackPatch.java delete mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ZoomHapticsPatch.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/Fingerprints.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableHapticFeedbackPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableHapticFeedbackPatch.java new file mode 100644 index 000000000..6ae49427a --- /dev/null +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableHapticFeedbackPatch.java @@ -0,0 +1,35 @@ +package app.revanced.extension.youtube.patches; + +import app.revanced.extension.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class DisableHapticFeedbackPatch { + + /** + * Injection point. + */ + public static boolean disableChapterVibrate() { + return Settings.DISABLE_HAPTIC_FEEDBACK_CHAPTERS.get(); + } + + /** + * Injection point. + */ + public static boolean disableSeekUndoVibrate() { + return Settings.DISABLE_HAPTIC_FEEDBACK_SEEK_UNDO.get(); + } + + /** + * Injection point. + */ + public static boolean disablePreciseSeekingVibrate() { + return Settings.DISABLE_HAPTIC_FEEDBACK_PRECISE_SEEKING.get(); + } + + /** + * Injection point. + */ + public static boolean disableZoomVibrate() { + return Settings.DISABLE_HAPTIC_FEEDBACK_ZOOM.get(); + } +} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ZoomHapticsPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ZoomHapticsPatch.java deleted file mode 100644 index 0367eb868..000000000 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ZoomHapticsPatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.extension.youtube.patches; - -import app.revanced.extension.youtube.settings.Settings; - -@SuppressWarnings("unused") -public class ZoomHapticsPatch { - public static boolean shouldVibrate() { - return !Settings.DISABLE_ZOOM_HAPTICS.get(); - } -} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 27c6f0d00..8f7b46421 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -309,7 +309,10 @@ public class Settings extends BaseSettings { public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE); public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false); - public static final BooleanSetting DISABLE_ZOOM_HAPTICS = new BooleanSetting("revanced_disable_zoom_haptics", TRUE); + public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_CHAPTERS = new BooleanSetting("revanced_disable_haptic_feedback_chapters", FALSE); + public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_PRECISE_SEEKING = new BooleanSetting("revanced_disable_haptic_feedback_precise_seeking", FALSE); + public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_SEEK_UNDO = new BooleanSetting("revanced_disable_haptic_feedback_seek_undo", FALSE); + public static final BooleanSetting DISABLE_HAPTIC_FEEDBACK_ZOOM = new BooleanSetting("revanced_disable_haptic_feedback_zoom", FALSE); public static final BooleanSetting EXTERNAL_BROWSER = new BooleanSetting("revanced_external_browser", TRUE, true); public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE); public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true, diff --git a/patches/api/patches.api b/patches/api/patches.api index 9bed69e1e..09dbd1698 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1399,6 +1399,10 @@ public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatchKt { public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatchKt { + public static final fun getDisableHapticFeedbackPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHookKt { public static final fun addImageUrlErrorCallbackHook (Ljava/lang/String;)V public static final fun addImageUrlHook (Ljava/lang/String;Z)V diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt new file mode 100644 index 000000000..977226560 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt @@ -0,0 +1,74 @@ +package app.revanced.patches.youtube.misc.hapticfeedback + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.misc.settings.PreferenceScreen +import app.revanced.patches.youtube.misc.settings.settingsPatch + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/DisableHapticFeedbackPatch;" + +@Suppress("unused") +val disableHapticFeedbackPatch = bytecodePatch( + name = "Disable haptic feedback", + description = "Adds an option to disable haptic feedback in the player for various actions.", +) { + dependsOn( + settingsPatch, + addResourcesPatch, + ) + + compatibleWith( + "com.google.android.youtube"( + "19.16.39", + "19.25.37", + "19.34.42", + "19.43.41", + "19.47.53", + "20.07.39", + "20.12.46", + ) + ) + + execute { + addResources("youtube", "misc.hapticfeedback.disableHapticFeedbackPatch") + + PreferenceScreen.PLAYER.addPreferences( + PreferenceScreenPreference( + "revanced_disable_haptic_feedback", + preferences = setOf( + SwitchPreference("revanced_disable_haptic_feedback_chapters"), + SwitchPreference("revanced_disable_haptic_feedback_precise_seeking"), + SwitchPreference("revanced_disable_haptic_feedback_seek_undo"), + SwitchPreference("revanced_disable_haptic_feedback_zoom"), + ) + ) + ) + + arrayOf( + markerHapticsFingerprint to "disableChapterVibrate", + scrubbingHapticsFingerprint to "disablePreciseSeekingVibrate", + seekUndoHapticsFingerprint to "disableSeekUndoVibrate", + zoomHapticsFingerprint to "disableZoomVibrate" + ).forEach { (fingerprint, methodName) -> + fingerprint.method.apply { + addInstructionsWithLabels( + 0, + """ + invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->$methodName()Z + move-result v0 + if-eqz v0, :vibrate + return-void + """, + ExternalLabel("vibrate", getInstruction(0)) + ) + } + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/Fingerprints.kt new file mode 100644 index 000000000..13efc4693 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/Fingerprints.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.youtube.misc.hapticfeedback + +import app.revanced.patcher.fingerprint + +internal val markerHapticsFingerprint = fingerprint { + returns("V") + strings("Failed to execute markers haptics vibrate.") +} + +internal val scrubbingHapticsFingerprint = fingerprint { + returns("V") + strings("Failed to haptics vibrate for fine scrubbing.") +} + +internal val seekUndoHapticsFingerprint = fingerprint { + returns("V") + strings("Failed to execute seek undo haptics vibrate.") +} + +internal val zoomHapticsFingerprint = fingerprint { + returns("V") + strings("Failed to haptics vibrate for video zoom") +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt deleted file mode 100644 index 65cb70769..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.youtube.misc.zoomhaptics - -import app.revanced.patcher.fingerprint - -internal val zoomHapticsFingerprint = fingerprint { - strings("Failed to haptics vibrate for video zoom") -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatch.kt index 0e961dfeb..44cde6002 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatch.kt @@ -1,54 +1,11 @@ package app.revanced.patches.youtube.misc.zoomhaptics -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.all.misc.resources.addResources -import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import app.revanced.patches.youtube.misc.settings.settingsPatch +import app.revanced.patches.youtube.misc.hapticfeedback.disableHapticFeedbackPatch +@Deprecated("Superseded by disableHapticFeedbackPatch", ReplaceWith("disableHapticFeedbackPatch")) val zoomHapticsPatch = bytecodePatch( - name = "Disable zoom haptics", description = "Adds an option to disable haptics when zooming.", ) { - dependsOn( - settingsPatch, - addResourcesPatch, - ) - - compatibleWith( - "com.google.android.youtube"( - "19.16.39", - "19.25.37", - "19.34.42", - "19.43.41", - "19.47.53", - "20.07.39", - "20.12.46", - ) - ) - - execute { - addResources("youtube", "misc.zoomhaptics.zoomHapticsPatch") - - PreferenceScreen.MISC.addPreferences( - SwitchPreference("revanced_disable_zoom_haptics"), - ) - - zoomHapticsFingerprint.method.apply { - addInstructionsWithLabels( - 0, - """ - invoke-static { }, Lapp/revanced/extension/youtube/patches/ZoomHapticsPatch;->shouldVibrate()Z - move-result v0 - if-nez v0, :vibrate - return-void - """, - ExternalLabel("vibrate", getInstruction(0)), - ) - } - } -} + dependsOn(disableHapticFeedbackPatch) +} \ No newline at end of file diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index d59675088..86561c683 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1390,6 +1390,22 @@ Enabling this can unlock higher video qualities" GmsCore Settings Settings for GmsCore + + Haptic feedback + Change haptic feedback + Disable chapters haptics + Chapters haptics is disabled + Chapters haptics is enabled + Disable precise seeking haptics + Precise seeking haptics is disabled + Precise seeking haptics is enabled + Disable seek undo haptics + Seek undo haptics is disabled + Seek undo haptics is enabled + Disable zoom haptics + Zoom haptics is disabled + Zoom haptics is enabled + If you recently changed your account login details, then uninstall and reinstall MicroG. @@ -1408,11 +1424,6 @@ Enabling this can unlock higher video qualities" Tracking query parameter is removed from links Tracking query parameter is not removed from links - - Disable zoom haptics - Haptics are disabled - Haptics are enabled - Force original audio language Using original audio language