diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/CheckWatchHistoryDomainNameResolutionPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CheckWatchHistoryDomainNameResolutionPatch.java similarity index 88% rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/CheckWatchHistoryDomainNameResolutionPatch.java rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CheckWatchHistoryDomainNameResolutionPatch.java index 62a0a0de8..ff2c55ade 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/CheckWatchHistoryDomainNameResolutionPatch.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CheckWatchHistoryDomainNameResolutionPatch.java @@ -1,4 +1,4 @@ -package app.revanced.extension.youtube.patches; +package app.revanced.extension.shared.patches; import static app.revanced.extension.shared.StringRef.str; @@ -13,8 +13,8 @@ import java.net.UnknownHostException; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.ui.CustomDialog; -import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") public class CheckWatchHistoryDomainNameResolutionPatch { @@ -49,7 +49,7 @@ public class CheckWatchHistoryDomainNameResolutionPatch { * Checks if s.youtube.com is blacklisted and playback history will fail to work. */ public static void checkDnsResolver(Activity context) { - if (!Utils.isNetworkConnected() || !Settings.CHECK_WATCH_HISTORY_DOMAIN_NAME.get()) return; + if (!Utils.isNetworkConnected() || !BaseSettings.CHECK_WATCH_HISTORY_DOMAIN_NAME.get()) return; Utils.runOnBackgroundThread(() -> { try { @@ -61,8 +61,8 @@ public class CheckWatchHistoryDomainNameResolutionPatch { // Prevent this false positive by verify youtube.com resolves. // If youtube.com does not resolve, then it's not a watch history domain resolving error // because the entire app will not work since no domains are resolving. - if (domainResolvesToValidIP(HISTORY_TRACKING_ENDPOINT) - || !domainResolvesToValidIP("youtube.com")) { + if (!domainResolvesToValidIP("youtube.com") + || domainResolvesToValidIP(HISTORY_TRACKING_ENDPOINT)) { return; } @@ -78,7 +78,7 @@ public class CheckWatchHistoryDomainNameResolutionPatch { () -> {}, // OK button action (just dismiss). () -> {}, // Cancel button action (just dismiss). str("revanced_check_watch_history_domain_name_dialog_ignore"), // Neutral button text. - () -> Settings.CHECK_WATCH_HISTORY_DOMAIN_NAME.save(false), // Neutral button action (Ignore). + () -> BaseSettings.CHECK_WATCH_HISTORY_DOMAIN_NAME.save(false), // Neutral button action (Ignore). true // Dismiss dialog on Neutral button click. ); 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 f42c38379..1eff30361 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 @@ -28,10 +28,16 @@ public class BaseSettings { public static final BooleanSetting SETTINGS_SEARCH_HISTORY = new BooleanSetting("revanced_settings_search_history", TRUE, true); public static final StringSetting SETTINGS_SEARCH_ENTRIES = new StringSetting("revanced_settings_search_entries", ""); + // + // Settings shared by YouTube and YouTube Music. + // + 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); + + public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false); } 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 63a8e9c8f..3a4bf598a 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 @@ -344,7 +344,6 @@ public class Settings extends BaseSettings { public static final BooleanSetting LOOP_VIDEO = new BooleanSetting("revanced_loop_video", FALSE); public static final BooleanSetting LOOP_VIDEO_BUTTON = new BooleanSetting("revanced_loop_video_button", 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_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); diff --git a/patches/api/patches.api b/patches/api/patches.api index f1b6c93a0..b63399a7a 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -405,6 +405,10 @@ public final class app/revanced/patches/music/misc/debugging/EnableDebuggingPatc public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/music/misc/dns/CheckWatchHistoryDomainNameResolutionPatchKt { + public static final fun getCheckWatchHistoryDomainNameResolutionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/music/misc/extension/SharedExtensionPatchKt { public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt new file mode 100644 index 000000000..d6ac3ef78 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.music.misc.dns + +import app.revanced.patches.music.misc.extension.sharedExtensionPatch +import app.revanced.patches.music.shared.mainActivityOnCreateFingerprint +import app.revanced.patches.shared.misc.dns.checkWatchHistoryDomainNameResolutionPatch + +val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameResolutionPatch( + block = { + dependsOn( + sharedExtensionPatch + ) + + compatibleWith( + "com.google.android.apps.youtube.music"( + "7.29.52", + "8.10.52" + ) + ) + }, + + mainActivityFingerprint = mainActivityOnCreateFingerprint +) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/SharedExtensionPatch.kt index 9351b600e..b10c321a4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/SharedExtensionPatch.kt @@ -1,9 +1,10 @@ package app.revanced.patches.music.misc.extension import app.revanced.patches.music.misc.extension.hooks.applicationInitHook +import app.revanced.patches.music.misc.extension.hooks.applicationInitOnCreateHook import app.revanced.patches.shared.misc.extension.sharedExtensionPatch val sharedExtensionPatch = sharedExtensionPatch( "music", - applicationInitHook, + applicationInitHook, applicationInitOnCreateHook ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt index 1e1a43f9a..60372d1aa 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt @@ -1,5 +1,6 @@ package app.revanced.patches.music.misc.extension.hooks +import app.revanced.patches.music.shared.YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE import app.revanced.patches.shared.misc.extension.extensionHook internal val applicationInitHook = extensionHook { @@ -8,3 +9,11 @@ internal val applicationInitHook = extensionHook { strings("activity") custom { method, _ -> method.name == "onCreate" } } + +internal val applicationInitOnCreateHook = extensionHook { + returns("V") + parameters("Landroid/os/Bundle;") + custom { method, classDef -> + method.name == "onCreate" && classDef.type == YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/shared/Fingerprints.kt new file mode 100644 index 000000000..d6c79197d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/music/shared/Fingerprints.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.music.shared + +import app.revanced.patcher.fingerprint + +internal const val YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE = "Lcom/google/android/apps/youtube/music/activities/MusicActivity;" + +internal val mainActivityOnCreateFingerprint = fingerprint { + returns("V") + parameters("Landroid/os/Bundle;") + custom { method, classDef -> + method.name == "onCreate" && classDef.type == YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt new file mode 100644 index 000000000..f409ee9b1 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt @@ -0,0 +1,36 @@ +package app.revanced.patches.shared.misc.dns + +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatchBuilder +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.all.misc.resources.addResources + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/shared/patches/CheckWatchHistoryDomainNameResolutionPatch;" + +/** + * Patch shared with YouTube and YT Music. + */ +internal fun checkWatchHistoryDomainNameResolutionPatch( + block: BytecodePatchBuilder.() -> Unit = {}, + executeBlock: BytecodePatchContext.() -> Unit = {}, + mainActivityFingerprint: Fingerprint +) = bytecodePatch( + name = "Check watch history domain name resolution", + description = "Checks if the device DNS server is preventing user watch history from being saved.", +) { + block() + + execute { + executeBlock() + + addResources("shared", "misc.dns.checkWatchHistoryDomainNameResolutionPatch") + + mainActivityFingerprint.method.addInstruction( + 0, + "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->checkDnsResolver(Landroid/app/Activity;)V", + ) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt index 699f8a983..5bd5da415 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt @@ -1,39 +1,23 @@ package app.revanced.patches.youtube.misc.dns -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.all.misc.resources.addResources -import app.revanced.patches.all.misc.resources.addResourcesPatch +import app.revanced.patches.shared.misc.dns.checkWatchHistoryDomainNameResolutionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint -private const val EXTENSION_CLASS_DESCRIPTOR = - "Lapp/revanced/extension/youtube/patches/CheckWatchHistoryDomainNameResolutionPatch;" - -val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch( - name = "Check watch history domain name resolution", - description = "Checks if the device DNS server is preventing user watch history from being saved.", -) { - dependsOn( - sharedExtensionPatch, - addResourcesPatch - ) - - compatibleWith( - "com.google.android.youtube"( - "19.34.42", - "20.07.39", - "20.13.41", - "20.14.43", +val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameResolutionPatch( + block = { + dependsOn( + sharedExtensionPatch ) - ) - execute { - addResources("youtube", "misc.dns.checkWatchHistoryDomainNameResolutionPatch") - - mainActivityOnCreateFingerprint.method.addInstruction( - 0, - "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->checkDnsResolver(Landroid/app/Activity;)V", + compatibleWith( + "com.google.android.youtube"( + "19.34.42", + "20.07.39", + "20.13.41", + "20.14.43", + ) ) - } -} + }, + mainActivityFingerprint = mainActivityOnCreateFingerprint +) diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index e5865731a..375d5ea69 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -30,6 +30,11 @@ Second \"item\" text" Patched %s days ago APK build date is corrupted + + Warning + Your watch history is not being saved.<br><br>This most likely is caused by a DNS ad blocker or network proxy.<br><br>To fix this, whitelist <b>s.youtube.com</b> or turn off all DNS blockers and proxies. + Do not show again + Settings ReVanced @@ -1522,11 +1527,6 @@ Tap here to learn more about DeArrow" Failed connecting to announcements provider Dismiss - - Warning - Your watch history is not being saved.<br><br>This most likely is caused by a DNS ad blocker or network proxy.<br><br>To fix this, whitelist <b>s.youtube.com</b> or turn off all DNS blockers and proxies. - Do not show again - Enable loop video Video will loop