diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/SanitizeSharingLinksPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/SanitizeSharingLinksPatch.java new file mode 100644 index 000000000..6952bdcd1 --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/SanitizeSharingLinksPatch.java @@ -0,0 +1,29 @@ +package app.revanced.extension.shared.patches; + +import app.revanced.extension.shared.settings.BaseSettings; + +/** + * YouTube and YouTube Music. + */ +@SuppressWarnings("unused") +public final class SanitizeSharingLinksPatch { + private static final String NEW_TRACKING_PARAMETER_REGEX = ".si=.+"; + private static final String OLD_TRACKING_PARAMETER_REGEX = ".feature=.+"; + + /** + * Injection point. + */ + public static String sanitize(String url) { + if (BaseSettings.SANITIZE_SHARED_LINKS.get()) { + url = url + .replaceAll(NEW_TRACKING_PARAMETER_REGEX, "") + .replaceAll(OLD_TRACKING_PARAMETER_REGEX, ""); + } + + if (BaseSettings.REPLACE_MUSIC_LINKS_WITH_YOUTUBE.get()) { + url = url.replace("music.youtube.com", "youtube.com"); + } + + return url; + } +} diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 0dd948aa8..f42c38379 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -31,4 +31,7 @@ public class BaseSettings { public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message"); public static final EnumSetting SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AppLanguage.DEFAULT, new AudioStreamLanguageOverrideAvailability()); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE, parent(SPOOF_VIDEO_STREAMS)); + + public static final BooleanSetting SANITIZE_SHARED_LINKS = new BooleanSetting("revanced_sanitize_sharing_links", TRUE); + public static final BooleanSetting REPLACE_MUSIC_LINKS_WITH_YOUTUBE = new BooleanSetting("revanced_replace_music_with_youtube", FALSE); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/RemoveTrackingQueryParameterPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/RemoveTrackingQueryParameterPatch.java deleted file mode 100644 index 3b05a239a..000000000 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/RemoveTrackingQueryParameterPatch.java +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.extension.youtube.patches; - -import app.revanced.extension.youtube.settings.Settings; - -@SuppressWarnings("unused") -public final class RemoveTrackingQueryParameterPatch { - private static final String NEW_TRACKING_PARAMETER_REGEX = ".si=.+"; - private static final String OLD_TRACKING_PARAMETER_REGEX = ".feature=.+"; - - public static String sanitize(String url) { - if (!Settings.REMOVE_TRACKING_QUERY_PARAMETER.get()) return url; - - return url - .replaceAll(NEW_TRACKING_PARAMETER_REGEX, "") - .replaceAll(OLD_TRACKING_PARAMETER_REGEX, ""); - } -} 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 916be8723..7980bb5fa 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 @@ -349,7 +349,6 @@ public class Settings extends BaseSettings { 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, "revanced_spoof_device_dimensions_user_dialog_message"); public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_61_48, true, parent(SPOOF_VIDEO_STREAMS)); diff --git a/patches/api/patches.api b/patches/api/patches.api index aeaab90db..76a7225f6 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -417,6 +417,10 @@ public final class app/revanced/patches/music/misc/gms/GmsCoreSupportPatchKt { public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/music/misc/privacy/SanitizeSharingLinksPatchKt { + public static final fun getSanitizeSharingLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/music/misc/settings/PreferenceScreen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen { public static final field INSTANCE Lapp/revanced/patches/music/misc/settings/PreferenceScreen; public fun commit (Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreenPreference;)V @@ -1664,6 +1668,10 @@ public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQuery public static final fun getRemoveTrackingQueryParameterPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/misc/privacy/SanitizeSharingLinksPatchKt { + public static final fun getSanitizeSharingLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatchKt { public static final fun getAddRecyclerViewTreeHook ()Lkotlin/jvm/functions/Function1; public static final fun getRecyclerViewTreeHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch; diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/privacy/SanitizeSharingLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/privacy/SanitizeSharingLinksPatch.kt new file mode 100644 index 000000000..e173b5c84 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/privacy/SanitizeSharingLinksPatch.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.music.misc.privacy + +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.misc.settings.PreferenceScreen +import app.revanced.patches.music.misc.settings.settingsPatch +import app.revanced.patches.shared.misc.privacy.sanitizeSharingLinksPatch + +@Suppress("unused") +val sanitizeSharingLinksPatch = sanitizeSharingLinksPatch( + block = { + dependsOn( + sharedExtensionPatch, + settingsPatch, + ) + + compatibleWith( + "com.google.android.apps.youtube.music"( + "7.29.52", + "8.10.52" + ) + ) + }, + preferenceScreen = PreferenceScreen.MISC, + replaceMusicLinksWithYouTube = true +) \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt similarity index 81% rename from patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt rename to patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt index 72734bba7..47de39348 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt @@ -1,10 +1,10 @@ -package app.revanced.patches.youtube.misc.privacy +package app.revanced.patches.shared.misc.privacy -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode -internal val copyTextFingerprint = fingerprint { +internal val youTubeCopyTextFingerprint = fingerprint { returns("V") parameters("L", "Ljava/util/Map;") opcodes( @@ -21,7 +21,7 @@ internal val copyTextFingerprint = fingerprint { strings("text/plain") } -internal val systemShareSheetFingerprint = fingerprint { +internal val youTubeSystemShareSheetFingerprint = fingerprint { returns("V") parameters("L", "Ljava/util/Map;") opcodes( @@ -31,7 +31,7 @@ internal val systemShareSheetFingerprint = fingerprint { strings("YTShare_Logging_Share_Intent_Endpoint_Byte_Array") } -internal val youtubeShareSheetFingerprint = fingerprint { +internal val youTubeShareSheetFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "Ljava/util/Map;") diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt new file mode 100644 index 000000000..860a253af --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt @@ -0,0 +1,89 @@ +package app.revanced.patches.shared.misc.privacy + +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.Match +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatchBuilder +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.resources.addResources +import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen +import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/shared/patches/SanitizeSharingLinksPatch;" + +internal fun sanitizeSharingLinksPatch( + block: BytecodePatchBuilder.() -> Unit = {}, + executeBlock: BytecodePatchContext.() -> Unit = {}, + preferenceScreen: BasePreferenceScreen.Screen, + replaceMusicLinksWithYouTube: Boolean = false +) = bytecodePatch( + name = "Sanitize sharing links", + description = "Adds an option to remove the tracking parameter from links you share.", +) { + block() + + dependsOn(addResourcesPatch) + + execute { + executeBlock() + + addResources("shared", "misc.privacy.sanitizeSharingLinksPatch") + + val sanitizePreference = SwitchPreference("revanced_sanitize_sharing_links") + + preferenceScreen.addPreferences( + if (replaceMusicLinksWithYouTube) { + PreferenceCategory( + titleKey = null, + sorting = Sorting.UNSORTED, + tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", + preferences = setOf( + sanitizePreference, + SwitchPreference("revanced_replace_music_with_youtube") + ) + ) + } else { + sanitizePreference + } + ) + + fun Fingerprint.hook( + getInsertIndex: Match.PatternMatch.() -> Int, + getUrlRegister: MutableMethod.(insertIndex: Int) -> Int, + ) { + val insertIndex = patternMatch!!.getInsertIndex() + val urlRegister = method.getUrlRegister(insertIndex) + + method.addInstructions( + insertIndex, + """ + invoke-static {v$urlRegister}, $EXTENSION_CLASS_DESCRIPTOR->sanitize(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$urlRegister + """ + ) + } + + // YouTube share sheet.\ + youTubeShareSheetFingerprint.hook(getInsertIndex = { startIndex + 1 }) { insertIndex -> + getInstruction(insertIndex - 1).registerA + } + + // Native system share sheet. + youTubeSystemShareSheetFingerprint.hook(getInsertIndex = { endIndex }) { insertIndex -> + getInstruction(insertIndex - 1).registerA + } + + youTubeCopyTextFingerprint.hook(getInsertIndex = { startIndex + 2 }) { insertIndex -> + getInstruction(insertIndex - 2).registerA + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt index 7e99f0177..937365c6a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt @@ -1,78 +1,9 @@ package app.revanced.patches.youtube.misc.privacy -import app.revanced.patcher.Fingerprint -import app.revanced.patcher.Match -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -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.extension.sharedExtensionPatch -import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import app.revanced.patches.youtube.misc.settings.settingsPatch -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -private const val EXTENSION_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/RemoveTrackingQueryParameterPatch;" - -val removeTrackingQueryParameterPatch = bytecodePatch( - name = "Remove tracking query parameter", - description = "Adds an option to remove the tracking parameter from links you share.", -) { - dependsOn( - sharedExtensionPatch, - settingsPatch, - addResourcesPatch, - ) - - compatibleWith( - "com.google.android.youtube"( - "19.34.42", - "19.43.41", - "20.07.39", - "20.13.41", - "20.14.43", - ) - ) - - execute { - addResources("youtube", "misc.privacy.removeTrackingQueryParameterPatch") - - PreferenceScreen.MISC.addPreferences( - SwitchPreference("revanced_remove_tracking_query_parameter"), - ) - - fun Fingerprint.hook( - getInsertIndex: Match.PatternMatch.() -> Int, - getUrlRegister: MutableMethod.(insertIndex: Int) -> Int, - ) { - val insertIndex = patternMatch!!.getInsertIndex() - val urlRegister = method.getUrlRegister(insertIndex) - - method.addInstructions( - insertIndex, - """ - invoke-static {v$urlRegister}, $EXTENSION_CLASS_DESCRIPTOR->sanitize(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$urlRegister - """, - ) - } - - // YouTube share sheet.\ - youtubeShareSheetFingerprint.hook(getInsertIndex = { startIndex + 1 }) { insertIndex -> - getInstruction(insertIndex - 1).registerA - } - - // Native system share sheet. - systemShareSheetFingerprint.hook(getInsertIndex = { endIndex }) { insertIndex -> - getInstruction(insertIndex - 1).registerA - } - - copyTextFingerprint.hook(getInsertIndex = { startIndex + 2 }) { insertIndex -> - getInstruction(insertIndex - 2).registerA - } - } +@Deprecated("Patch was renamed", ReplaceWith("sanitizeSharingLinksPatch")) +@Suppress("unused") +val removeTrackingQueryParameterPatch = bytecodePatch{ + dependsOn(sanitizeSharingLinksPatch) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/SanitizeSharingLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/SanitizeSharingLinksPatch.kt new file mode 100644 index 000000000..d21388b94 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/SanitizeSharingLinksPatch.kt @@ -0,0 +1,26 @@ +package app.revanced.patches.youtube.misc.privacy + +import app.revanced.patches.shared.misc.privacy.sanitizeSharingLinksPatch +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.settings.PreferenceScreen +import app.revanced.patches.youtube.misc.settings.settingsPatch + +@Suppress("unused") +val sanitizeSharingLinksPatch = sanitizeSharingLinksPatch( + block = { + dependsOn( + sharedExtensionPatch, + settingsPatch, + ) + compatibleWith( + "com.google.android.youtube"( + "19.34.42", + "19.43.41", + "20.07.39", + "20.13.41", + "20.14.43", + ) + ) + }, + preferenceScreen = PreferenceScreen.MISC +) diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index df49d0155..959876cb6 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -196,6 +196,14 @@ You will not be notified of any unexpected events." Clears all stored ReVanced debug logs Logs cleared + + Remove tracking query parameter + Tracking query parameter is removed from links + Tracking query parameter is not removed from links + Change share links to youtube.com + Shared links use youtube.com + Shared links use music.youtube.com + @@ -1562,11 +1570,6 @@ Enabling this can unlock higher video qualities" Opening links in external browser Opening links in in-app browser - - Remove tracking query parameter - Tracking query parameter is removed from links - Tracking query parameter is not removed from links - Force original audio language Using original audio language